@promptbook/node 0.81.0-8 → 0.82.0-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -4
- package/esm/index.es.js +1948 -1766
- package/esm/index.es.js.map +1 -1
- package/esm/typings/books/index.d.ts +38 -0
- package/esm/typings/src/_packages/core.index.d.ts +12 -4
- package/esm/typings/src/_packages/markdown-utils.index.d.ts +2 -2
- package/esm/typings/src/_packages/node.index.d.ts +0 -2
- package/esm/typings/src/_packages/remote-client.index.d.ts +7 -3
- package/esm/typings/src/_packages/remote-server.index.d.ts +2 -2
- package/esm/typings/src/_packages/templates.index.d.ts +2 -2
- package/esm/typings/src/_packages/types.index.d.ts +34 -30
- package/esm/typings/src/_packages/utils.index.d.ts +2 -0
- package/esm/typings/src/_packages/wizzard.index.d.ts +44 -0
- package/esm/typings/src/cli/cli-commands/make.d.ts +1 -1
- package/esm/typings/src/cli/cli-commands/run.d.ts +2 -2
- package/esm/typings/src/collection/constructors/createCollectionFromDirectory.d.ts +11 -0
- package/esm/typings/src/collection/constructors/createCollectionFromUrl.d.ts +1 -1
- package/esm/typings/src/commands/index.d.ts +1 -1
- package/esm/typings/src/config.d.ts +3 -3
- package/esm/typings/src/conversion/compilePipeline.d.ts +1 -4
- package/esm/typings/src/conversion/compilePipelineOnRemoteServer.d.ts +18 -0
- package/esm/typings/src/conversion/{precompilePipeline.d.ts → parsePipeline.d.ts} +3 -3
- package/esm/typings/src/conversion/prettify/renderPipelineMermaidOptions.d.ts +3 -3
- package/esm/typings/src/conversion/validation/validatePipeline.d.ts +7 -7
- package/esm/typings/src/errors/utils/getErrorReportUrl.d.ts +1 -1
- package/esm/typings/src/execution/PipelineExecutor.d.ts +2 -2
- package/esm/typings/src/execution/createPipelineExecutor/10-executePipeline.d.ts +2 -2
- package/esm/typings/src/formfactors/generator/GeneratorFormfactorDefinition.d.ts +9 -4
- package/esm/typings/src/formfactors/image-generator/ImageGeneratorFormfactorDefinition.d.ts +24 -0
- package/esm/typings/src/formfactors/index.d.ts +31 -9
- package/esm/typings/src/high-level-abstractions/_common/HighLevelAbstraction.d.ts +1 -1
- package/esm/typings/src/high-level-abstractions/index.d.ts +3 -3
- package/esm/typings/src/high-level-abstractions/quick-chatbot/QuickChatbotHla.d.ts +3 -0
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsConfigurationFromEnv.d.ts +1 -1
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForTestingAndScriptsAndPlayground.d.ts +1 -1
- package/esm/typings/src/llm-providers/_common/register/{$provideLlmToolsForCli.d.ts → $provideLlmToolsForWizzardOrCli.d.ts} +2 -2
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsFromEnv.d.ts +1 -1
- package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionToolsOptions.d.ts +1 -1
- package/esm/typings/src/llm-providers/anthropic-claude/anthropic-claude-models.d.ts +1 -1
- package/esm/typings/src/llm-providers/anthropic-claude/createAnthropicClaudeExecutionTools.d.ts +2 -2
- package/esm/typings/src/llm-providers/anthropic-claude/playground/playground.d.ts +2 -2
- package/esm/typings/src/llm-providers/anthropic-claude/register-configuration.d.ts +1 -0
- package/esm/typings/src/llm-providers/anthropic-claude/register-constructor.d.ts +2 -0
- package/esm/typings/src/llm-providers/azure-openai/register-configuration.d.ts +1 -0
- package/esm/typings/src/llm-providers/azure-openai/register-constructor.d.ts +1 -0
- package/esm/typings/src/llm-providers/google/register-configuration.d.ts +1 -0
- package/esm/typings/src/llm-providers/google/register-constructor.d.ts +1 -0
- package/esm/typings/src/llm-providers/openai/playground/playground.d.ts +1 -1
- package/esm/typings/src/llm-providers/openai/register-configuration.d.ts +2 -0
- package/esm/typings/src/llm-providers/openai/register-constructor.d.ts +2 -0
- package/esm/typings/src/llm-providers/remote/RemoteLlmExecutionTools.d.ts +1 -1
- package/esm/typings/src/llm-providers/vercel/playground/playground.d.ts +1 -1
- package/esm/typings/src/other/templates/getBookTemplates.d.ts +22 -0
- package/esm/typings/src/personas/preparePersona.d.ts +4 -4
- package/esm/typings/src/pipeline/PipelineString.d.ts +0 -3
- package/esm/typings/src/pipeline/book-notation.d.ts +14 -0
- package/esm/typings/src/pipeline/isValidPipelineString.d.ts +13 -0
- package/esm/typings/src/pipeline/isValidPipelineString.test.d.ts +4 -0
- package/esm/typings/src/pipeline/validatePipelineString.d.ts +14 -0
- package/esm/typings/src/prepare/isPipelinePrepared.d.ts +3 -1
- package/esm/typings/src/prepare/preparePipeline.d.ts +4 -2
- package/esm/typings/src/prepare/preparePipelineOnRemoteServer.d.ts +14 -0
- package/esm/typings/src/prepare/prepareTasks.d.ts +1 -1
- package/esm/typings/src/{llm-providers/remote → remote-server}/interfaces/PromptbookServer_Error.d.ts +1 -1
- package/esm/typings/src/{llm-providers/remote → remote-server}/interfaces/PromptbookServer_ListModels_Request.d.ts +4 -4
- package/esm/typings/src/{llm-providers/remote → remote-server}/interfaces/PromptbookServer_ListModels_Response.d.ts +1 -1
- package/esm/typings/src/{llm-providers/remote → remote-server}/interfaces/PromptbookServer_Prompt_Progress.d.ts +1 -1
- package/esm/typings/src/{llm-providers/remote → remote-server}/interfaces/PromptbookServer_Prompt_Request.d.ts +5 -5
- package/esm/typings/src/{llm-providers/remote → remote-server}/interfaces/PromptbookServer_Prompt_Response.d.ts +1 -1
- package/esm/typings/src/{llm-providers/remote → remote-server}/interfaces/RemoteLlmExecutionToolsOptions.d.ts +7 -7
- package/esm/typings/src/{llm-providers/remote → remote-server}/interfaces/RemoteServerOptions.d.ts +10 -10
- package/esm/typings/src/scrapers/_common/Converter.d.ts +1 -0
- package/esm/typings/src/scrapers/_common/Scraper.d.ts +1 -1
- package/esm/typings/src/scrapers/_common/ScraperIntermediateSource.d.ts +3 -0
- package/esm/typings/src/scrapers/_common/register/ScraperAndConverterMetadata.d.ts +2 -0
- package/esm/typings/src/scrapers/_common/utils/scraperFetch.d.ts +3 -0
- package/esm/typings/src/scrapers/document/register-constructor.d.ts +1 -0
- package/esm/typings/src/scrapers/document/register-metadata.d.ts +1 -0
- package/esm/typings/src/scrapers/document-legacy/register-constructor.d.ts +1 -0
- package/esm/typings/src/scrapers/document-legacy/register-metadata.d.ts +1 -0
- package/esm/typings/src/scrapers/markdown/register-constructor.d.ts +1 -0
- package/esm/typings/src/scrapers/markdown/register-metadata.d.ts +1 -0
- package/esm/typings/src/scrapers/pdf/PdfScraper.d.ts +1 -0
- package/esm/typings/src/scrapers/pdf/createPdfScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/pdf/register-constructor.d.ts +1 -0
- package/esm/typings/src/scrapers/pdf/register-metadata.d.ts +2 -1
- package/esm/typings/src/scrapers/website/createWebsiteScraper.d.ts +3 -1
- package/esm/typings/src/scrapers/website/register-constructor.d.ts +1 -0
- package/esm/typings/src/scrapers/website/register-metadata.d.ts +1 -0
- package/esm/typings/src/scripting/javascript/JavascriptEvalExecutionTools.test.d.ts +1 -1
- package/esm/typings/src/scripting/javascript/utils/preserve.d.ts +2 -1
- package/esm/typings/src/types/typeAliases.d.ts +16 -2
- package/esm/typings/src/utils/markdown/flattenMarkdown.d.ts +1 -1
- package/esm/typings/src/utils/markdown/{removeContentComments.d.ts → removeMarkdownComments.d.ts} +2 -2
- package/esm/typings/src/utils/organization/$sideEffect.d.ts +9 -0
- package/esm/typings/src/utils/serialization/checkSerializableAsJson.d.ts +1 -1
- package/esm/typings/src/utils/serialization/isSerializableAsJson.d.ts +2 -2
- package/esm/typings/src/utils/validators/filePath/isRootPath.d.ts +12 -0
- package/esm/typings/src/utils/validators/filePath/isRootPath.test.d.ts +4 -0
- package/esm/typings/src/utils/validators/filePath/isValidFilePath.d.ts +3 -0
- package/esm/typings/src/wizzard/$getCompiledBook.d.ts +16 -0
- package/esm/typings/src/wizzard/wizzard.d.ts +52 -8
- package/package.json +2 -2
- package/umd/index.umd.js +1947 -1766
- package/umd/index.umd.js.map +1 -1
- package/esm/typings/src/other/templates/getBookTemplate.d.ts +0 -21
- package/esm/typings/src/scripting/javascript/utils/unknownToString.d.ts +0 -8
- /package/esm/typings/src/conversion/{precompilePipeline.test.d.ts → parsePipeline.test.d.ts} +0 -0
- /package/esm/typings/src/{llm-providers/remote → remote-server}/startRemoteServer.d.ts +0 -0
- /package/esm/typings/src/utils/markdown/{removeContentComments.test.d.ts → removeMarkdownComments.test.d.ts} +0 -0
package/esm/index.es.js
CHANGED
|
@@ -28,7 +28,7 @@ var BOOK_LANGUAGE_VERSION = '1.0.0';
|
|
|
28
28
|
* @generated
|
|
29
29
|
* @see https://github.com/webgptorg/promptbook
|
|
30
30
|
*/
|
|
31
|
-
var PROMPTBOOK_ENGINE_VERSION = '0.81.0-
|
|
31
|
+
var PROMPTBOOK_ENGINE_VERSION = '0.81.0-23';
|
|
32
32
|
/**
|
|
33
33
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
34
34
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -198,7 +198,7 @@ var ADMIN_GITHUB_NAME = 'hejny';
|
|
|
198
198
|
*
|
|
199
199
|
* @public exported from `@promptbook/core`
|
|
200
200
|
*/
|
|
201
|
-
var
|
|
201
|
+
var DEFAULT_BOOK_TITLE = "\u2728 Untitled Book";
|
|
202
202
|
// <- TODO: [🧠] Better system for generator warnings - not always "code" and "by `@promptbook/cli`"
|
|
203
203
|
/**
|
|
204
204
|
* The maximum number of iterations for a loops
|
|
@@ -309,1412 +309,834 @@ true);
|
|
|
309
309
|
* TODO: [🧠][🧜♂️] Maybe join remoteUrl and path into single value
|
|
310
310
|
*/
|
|
311
311
|
|
|
312
|
-
/**
|
|
313
|
-
* Orders JSON object by keys
|
|
314
|
-
*
|
|
315
|
-
* @returns The same type of object as the input re-ordered
|
|
316
|
-
* @public exported from `@promptbook/utils`
|
|
317
|
-
*/
|
|
318
|
-
function orderJson(options) {
|
|
319
|
-
var value = options.value, order = options.order;
|
|
320
|
-
var orderedValue = __assign(__assign({}, (order === undefined ? {} : Object.fromEntries(order.map(function (key) { return [key, undefined]; })))), value);
|
|
321
|
-
return orderedValue;
|
|
322
|
-
}
|
|
312
|
+
var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book.md",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.md`\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.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.book.md",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.md`\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.md"},{title:"Prepare Knowledge-piece Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.book.md",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- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\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.md`\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- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\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.md"},{title:"Prepare Persona",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.book.md",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.md`\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.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-title.book.md",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 task:\n\n> {book}\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Title starts with emoticon",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.md`\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 task:\n\n> {book}\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Title starts with emoticon\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-title.book.md"}];
|
|
323
313
|
|
|
324
314
|
/**
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
* Note: `$` is used to indicate that this function is not a pure function - it mutates given object
|
|
328
|
-
* Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
|
|
315
|
+
* Function isValidJsonString will tell you if the string is valid JSON or not
|
|
329
316
|
*
|
|
330
|
-
* @returns The same object as the input, but deeply frozen
|
|
331
317
|
* @public exported from `@promptbook/utils`
|
|
332
318
|
*/
|
|
333
|
-
function
|
|
334
|
-
var e_1, _a;
|
|
335
|
-
if (Array.isArray(objectValue)) {
|
|
336
|
-
return Object.freeze(objectValue.map(function (item) { return $deepFreeze(item); }));
|
|
337
|
-
}
|
|
338
|
-
var propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
319
|
+
function isValidJsonString(value /* <- [👨⚖️] */) {
|
|
339
320
|
try {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
var value = objectValue[propertyName];
|
|
343
|
-
if (value && typeof value === 'object') {
|
|
344
|
-
$deepFreeze(value);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
321
|
+
JSON.parse(value);
|
|
322
|
+
return true;
|
|
347
323
|
}
|
|
348
|
-
catch (
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
if (propertyNames_1_1 && !propertyNames_1_1.done && (_a = propertyNames_1.return)) _a.call(propertyNames_1);
|
|
324
|
+
catch (error) {
|
|
325
|
+
if (!(error instanceof Error)) {
|
|
326
|
+
throw error;
|
|
352
327
|
}
|
|
353
|
-
|
|
328
|
+
if (error.message.includes('Unexpected token')) {
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
return false;
|
|
354
332
|
}
|
|
355
|
-
Object.freeze(objectValue);
|
|
356
|
-
return objectValue;
|
|
357
|
-
}
|
|
358
|
-
/**
|
|
359
|
-
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
360
|
-
*/
|
|
361
|
-
|
|
362
|
-
/**
|
|
363
|
-
* Make error report URL for the given error
|
|
364
|
-
*
|
|
365
|
-
* @private !!!!!!
|
|
366
|
-
*/
|
|
367
|
-
function getErrorReportUrl(error) {
|
|
368
|
-
var report = {
|
|
369
|
-
title: "\uD83D\uDC1C Error report from ".concat(NAME),
|
|
370
|
-
body: spaceTrim(function (block) { return "\n\n\n `".concat(error.name || 'Error', "` has occurred in the [").concat(NAME, "], please look into it @").concat(ADMIN_GITHUB_NAME, ".\n\n ```\n ").concat(block(error.message || '(no error message)'), "\n ```\n\n\n ## More info:\n\n - **Promptbook engine version:** ").concat(PROMPTBOOK_ENGINE_VERSION, "\n - **Book language version:** ").concat(BOOK_LANGUAGE_VERSION, "\n - **Time:** ").concat(new Date().toISOString(), "\n\n <details>\n <summary>Stack trace:</summary>\n\n ## Stack trace:\n\n ```stacktrace\n ").concat(block(error.stack || '(empty)'), "\n ```\n </details>\n\n "); }),
|
|
371
|
-
};
|
|
372
|
-
var reportUrl = new URL("https://github.com/webgptorg/promptbook/issues/new");
|
|
373
|
-
reportUrl.searchParams.set('labels', 'bug');
|
|
374
|
-
reportUrl.searchParams.set('assignees', ADMIN_GITHUB_NAME);
|
|
375
|
-
reportUrl.searchParams.set('title', report.title);
|
|
376
|
-
reportUrl.searchParams.set('body', report.body);
|
|
377
|
-
return reportUrl;
|
|
378
333
|
}
|
|
379
334
|
|
|
380
335
|
/**
|
|
381
|
-
* This error
|
|
336
|
+
* This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
|
|
382
337
|
*
|
|
383
338
|
* @public exported from `@promptbook/core`
|
|
384
339
|
*/
|
|
385
|
-
var
|
|
386
|
-
__extends(
|
|
387
|
-
function
|
|
388
|
-
var _this = _super.call(this,
|
|
389
|
-
_this.name = '
|
|
390
|
-
Object.setPrototypeOf(_this,
|
|
340
|
+
var ParseError = /** @class */ (function (_super) {
|
|
341
|
+
__extends(ParseError, _super);
|
|
342
|
+
function ParseError(message) {
|
|
343
|
+
var _this = _super.call(this, message) || this;
|
|
344
|
+
_this.name = 'ParseError';
|
|
345
|
+
Object.setPrototypeOf(_this, ParseError.prototype);
|
|
391
346
|
return _this;
|
|
392
347
|
}
|
|
393
|
-
return
|
|
348
|
+
return ParseError;
|
|
394
349
|
}(Error));
|
|
350
|
+
/**
|
|
351
|
+
* TODO: Maybe split `ParseError` and `ApplyError`
|
|
352
|
+
*/
|
|
395
353
|
|
|
396
354
|
/**
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
*
|
|
400
|
-
* - Almost all primitives are serializable BUT:
|
|
401
|
-
* - `undefined` is not serializable
|
|
402
|
-
* - `NaN` is not serializable
|
|
403
|
-
* - Objects and arrays are serializable if all their properties are serializable
|
|
404
|
-
* - Functions are not serializable
|
|
405
|
-
* - Circular references are not serializable
|
|
406
|
-
* - `Date` objects are not serializable
|
|
407
|
-
* - `Map` and `Set` objects are not serializable
|
|
408
|
-
* - `RegExp` objects are not serializable
|
|
409
|
-
* - `Error` objects are not serializable
|
|
410
|
-
* - `Symbol` objects are not serializable
|
|
411
|
-
* - And much more...
|
|
355
|
+
* Function `validatePipelineString` will validate the if the string is a valid pipeline string
|
|
356
|
+
* It does not check if the string is fully logically correct, but if it is a string that can be a pipeline string or the string looks completely different.
|
|
412
357
|
*
|
|
413
|
-
* @
|
|
414
|
-
* @
|
|
358
|
+
* @param {string} pipelineString the candidate for a pipeline string
|
|
359
|
+
* @returns {PipelineString} the same string as input, but validated as valid
|
|
360
|
+
* @throws {ParseError} if the string is not a valid pipeline string
|
|
361
|
+
* @public exported from `@promptbook/core`
|
|
415
362
|
*/
|
|
416
|
-
function
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
if (value === undefined) {
|
|
420
|
-
throw new UnexpectedError("".concat(name, " is undefined"));
|
|
421
|
-
}
|
|
422
|
-
else if (value === null) {
|
|
423
|
-
return;
|
|
424
|
-
}
|
|
425
|
-
else if (typeof value === 'boolean') {
|
|
426
|
-
return;
|
|
427
|
-
}
|
|
428
|
-
else if (typeof value === 'number' && !isNaN(value)) {
|
|
429
|
-
return;
|
|
430
|
-
}
|
|
431
|
-
else if (typeof value === 'string') {
|
|
432
|
-
return;
|
|
433
|
-
}
|
|
434
|
-
else if (typeof value === 'symbol') {
|
|
435
|
-
throw new UnexpectedError("".concat(name, " is symbol"));
|
|
436
|
-
}
|
|
437
|
-
else if (typeof value === 'function') {
|
|
438
|
-
throw new UnexpectedError("".concat(name, " is function"));
|
|
439
|
-
}
|
|
440
|
-
else if (typeof value === 'object' && Array.isArray(value)) {
|
|
441
|
-
for (var i = 0; i < value.length; i++) {
|
|
442
|
-
checkSerializableAsJson({ name: "".concat(name, "[").concat(i, "]"), value: value[i], message: message });
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
else if (typeof value === 'object') {
|
|
446
|
-
if (value instanceof Date) {
|
|
447
|
-
throw new UnexpectedError(spaceTrim(function (block) { return "\n `".concat(name, "` is Date\n\n Use `string_date_iso8601` instead\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n "); }));
|
|
448
|
-
}
|
|
449
|
-
else if (value instanceof Map) {
|
|
450
|
-
throw new UnexpectedError("".concat(name, " is Map"));
|
|
451
|
-
}
|
|
452
|
-
else if (value instanceof Set) {
|
|
453
|
-
throw new UnexpectedError("".concat(name, " is Set"));
|
|
454
|
-
}
|
|
455
|
-
else if (value instanceof RegExp) {
|
|
456
|
-
throw new UnexpectedError("".concat(name, " is RegExp"));
|
|
457
|
-
}
|
|
458
|
-
else if (value instanceof Error) {
|
|
459
|
-
throw new UnexpectedError(spaceTrim(function (block) { return "\n `".concat(name, "` is unserialized Error\n\n Use function `serializeError`\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n\n "); }));
|
|
460
|
-
}
|
|
461
|
-
else {
|
|
462
|
-
try {
|
|
463
|
-
for (var _b = __values(Object.entries(value)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
464
|
-
var _d = __read(_c.value, 2), subName = _d[0], subValue = _d[1];
|
|
465
|
-
if (subValue === undefined) {
|
|
466
|
-
// Note: undefined in object is serializable - it is just omited
|
|
467
|
-
continue;
|
|
468
|
-
}
|
|
469
|
-
checkSerializableAsJson({ name: "".concat(name, ".").concat(subName), value: subValue, message: message });
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
473
|
-
finally {
|
|
474
|
-
try {
|
|
475
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
476
|
-
}
|
|
477
|
-
finally { if (e_1) throw e_1.error; }
|
|
478
|
-
}
|
|
479
|
-
try {
|
|
480
|
-
JSON.stringify(value); // <- TODO: [0]
|
|
481
|
-
}
|
|
482
|
-
catch (error) {
|
|
483
|
-
if (!(error instanceof Error)) {
|
|
484
|
-
throw error;
|
|
485
|
-
}
|
|
486
|
-
throw new UnexpectedError(spaceTrim(function (block) { return "\n `".concat(name, "` is not serializable\n\n ").concat(block(error.toString()), "\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n "); }));
|
|
487
|
-
}
|
|
488
|
-
/*
|
|
489
|
-
TODO: [0] Is there some more elegant way to check circular references?
|
|
490
|
-
const seen = new Set();
|
|
491
|
-
const stack = [{ value }];
|
|
492
|
-
while (stack.length > 0) {
|
|
493
|
-
const { value } = stack.pop()!;
|
|
494
|
-
if (typeof value === 'object' && value !== null) {
|
|
495
|
-
if (seen.has(value)) {
|
|
496
|
-
throw new UnexpectedError(`${name} has circular reference`);
|
|
497
|
-
}
|
|
498
|
-
seen.add(value);
|
|
499
|
-
if (Array.isArray(value)) {
|
|
500
|
-
stack.push(...value.map((value) => ({ value })));
|
|
501
|
-
} else {
|
|
502
|
-
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
*/
|
|
507
|
-
return;
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
else {
|
|
511
|
-
throw new UnexpectedError(spaceTrim(function (block) { return "\n `".concat(name, "` is unknown type\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n "); }));
|
|
363
|
+
function validatePipelineString(pipelineString) {
|
|
364
|
+
if (isValidJsonString(pipelineString)) {
|
|
365
|
+
throw new ParseError('Expected a book, but got a JSON string');
|
|
512
366
|
}
|
|
367
|
+
// <- TODO: Implement the validation + add tests when the pipeline logic considered as invalid
|
|
368
|
+
return pipelineString;
|
|
513
369
|
}
|
|
514
370
|
/**
|
|
515
|
-
* TODO:
|
|
516
|
-
* TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
|
|
517
|
-
* Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
371
|
+
* TODO: [🧠][🈴] Where is the best location for this file
|
|
518
372
|
*/
|
|
519
373
|
|
|
520
374
|
/**
|
|
521
|
-
*
|
|
375
|
+
* Prettify the html code
|
|
522
376
|
*
|
|
523
|
-
* @
|
|
377
|
+
* @param content raw html code
|
|
378
|
+
* @returns formatted html code
|
|
379
|
+
* @private withing the package because of HUGE size of prettier dependency
|
|
524
380
|
*/
|
|
525
|
-
function
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
381
|
+
function prettifyMarkdown(content) {
|
|
382
|
+
try {
|
|
383
|
+
return format(content, {
|
|
384
|
+
parser: 'markdown',
|
|
385
|
+
plugins: [parserHtml],
|
|
386
|
+
// TODO: DRY - make some import or auto-copy of .prettierrc
|
|
387
|
+
endOfLine: 'lf',
|
|
388
|
+
tabWidth: 4,
|
|
389
|
+
singleQuote: true,
|
|
390
|
+
trailingComma: 'all',
|
|
391
|
+
arrowParens: 'always',
|
|
392
|
+
printWidth: 120,
|
|
393
|
+
htmlWhitespaceSensitivity: 'ignore',
|
|
394
|
+
jsxBracketSameLine: false,
|
|
395
|
+
bracketSpacing: true,
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
catch (error) {
|
|
399
|
+
// TODO: [🟥] Detect browser / node and make it colorfull
|
|
400
|
+
console.error('There was an error with prettifying the markdown, using the original as the fallback', {
|
|
401
|
+
error: error,
|
|
402
|
+
html: content,
|
|
403
|
+
});
|
|
404
|
+
return content;
|
|
405
|
+
}
|
|
539
406
|
}
|
|
407
|
+
|
|
540
408
|
/**
|
|
541
|
-
*
|
|
409
|
+
* Makes first letter of a string uppercase
|
|
410
|
+
*
|
|
411
|
+
* @public exported from `@promptbook/utils`
|
|
542
412
|
*/
|
|
413
|
+
function capitalize(word) {
|
|
414
|
+
return word.substring(0, 1).toUpperCase() + word.substring(1);
|
|
415
|
+
}
|
|
543
416
|
|
|
544
417
|
/**
|
|
545
|
-
*
|
|
418
|
+
* Converts promptbook in JSON format to string format
|
|
546
419
|
*
|
|
547
|
-
*
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
* Note: This function does not mutates the given object
|
|
553
|
-
*
|
|
554
|
-
* @returns The same type of object as the input but read-only and re-ordered
|
|
555
|
-
* @public exported from `@promptbook/utils`
|
|
420
|
+
* @deprecated TODO: [🥍][🧠] Backup original files in `PipelineJson` same as in Promptbook.studio
|
|
421
|
+
* @param pipelineJson Promptbook in JSON format (.book.json)
|
|
422
|
+
* @returns Promptbook in string format (.book.md)
|
|
423
|
+
* @public exported from `@promptbook/core`
|
|
556
424
|
*/
|
|
557
|
-
function
|
|
558
|
-
var
|
|
559
|
-
|
|
560
|
-
var
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
425
|
+
function pipelineJsonToString(pipelineJson) {
|
|
426
|
+
var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e, e_6, _f;
|
|
427
|
+
var title = pipelineJson.title, pipelineUrl = pipelineJson.pipelineUrl, bookVersion = pipelineJson.bookVersion, description = pipelineJson.description, parameters = pipelineJson.parameters, tasks = pipelineJson.tasks;
|
|
428
|
+
var pipelineString = "# ".concat(title);
|
|
429
|
+
if (description) {
|
|
430
|
+
pipelineString += '\n\n';
|
|
431
|
+
pipelineString += description;
|
|
432
|
+
}
|
|
433
|
+
var commands = [];
|
|
434
|
+
if (pipelineUrl) {
|
|
435
|
+
commands.push("PIPELINE URL ".concat(pipelineUrl));
|
|
436
|
+
}
|
|
437
|
+
if (bookVersion !== "undefined") {
|
|
438
|
+
commands.push("BOOK VERSION ".concat(bookVersion));
|
|
439
|
+
}
|
|
440
|
+
// TODO: [main] !!5 This increases size of the bundle and is probbably not necessary
|
|
441
|
+
pipelineString = prettifyMarkdown(pipelineString);
|
|
442
|
+
try {
|
|
443
|
+
for (var _g = __values(parameters.filter(function (_a) {
|
|
444
|
+
var isInput = _a.isInput;
|
|
445
|
+
return isInput;
|
|
446
|
+
})), _h = _g.next(); !_h.done; _h = _g.next()) {
|
|
447
|
+
var parameter = _h.value;
|
|
448
|
+
commands.push("INPUT PARAMETER ".concat(taskParameterJsonToString(parameter)));
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
452
|
+
finally {
|
|
453
|
+
try {
|
|
454
|
+
if (_h && !_h.done && (_a = _g.return)) _a.call(_g);
|
|
455
|
+
}
|
|
456
|
+
finally { if (e_1) throw e_1.error; }
|
|
457
|
+
}
|
|
458
|
+
try {
|
|
459
|
+
for (var _j = __values(parameters.filter(function (_a) {
|
|
460
|
+
var isOutput = _a.isOutput;
|
|
461
|
+
return isOutput;
|
|
462
|
+
})), _k = _j.next(); !_k.done; _k = _j.next()) {
|
|
463
|
+
var parameter = _k.value;
|
|
464
|
+
commands.push("OUTPUT PARAMETER ".concat(taskParameterJsonToString(parameter)));
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
468
|
+
finally {
|
|
469
|
+
try {
|
|
470
|
+
if (_k && !_k.done && (_b = _j.return)) _b.call(_j);
|
|
471
|
+
}
|
|
472
|
+
finally { if (e_2) throw e_2.error; }
|
|
473
|
+
}
|
|
474
|
+
pipelineString += '\n\n';
|
|
475
|
+
pipelineString += commands.map(function (command) { return "- ".concat(command); }).join('\n');
|
|
476
|
+
try {
|
|
477
|
+
for (var tasks_1 = __values(tasks), tasks_1_1 = tasks_1.next(); !tasks_1_1.done; tasks_1_1 = tasks_1.next()) {
|
|
478
|
+
var task = tasks_1_1.value;
|
|
479
|
+
var
|
|
480
|
+
/* Note: Not using:> name, */
|
|
481
|
+
title_1 = task.title, description_1 = task.description,
|
|
482
|
+
/* Note: dependentParameterNames, */
|
|
483
|
+
jokers = task.jokerParameterNames, taskType = task.taskType, content = task.content, postprocessing = task.postprocessingFunctionNames, expectations = task.expectations, format = task.format, resultingParameterName = task.resultingParameterName;
|
|
484
|
+
pipelineString += '\n\n';
|
|
485
|
+
pipelineString += "## ".concat(title_1);
|
|
486
|
+
if (description_1) {
|
|
487
|
+
pipelineString += '\n\n';
|
|
488
|
+
pipelineString += description_1;
|
|
489
|
+
}
|
|
490
|
+
var commands_1 = [];
|
|
491
|
+
var contentLanguage = 'text';
|
|
492
|
+
if (taskType === 'PROMPT_TASK') {
|
|
493
|
+
var modelRequirements = task.modelRequirements;
|
|
494
|
+
var _l = modelRequirements || {}, modelName = _l.modelName, modelVariant = _l.modelVariant;
|
|
495
|
+
// Note: Do nothing, it is default
|
|
496
|
+
// commands.push(`PROMPT`);
|
|
497
|
+
if (modelVariant) {
|
|
498
|
+
commands_1.push("MODEL VARIANT ".concat(capitalize(modelVariant)));
|
|
499
|
+
}
|
|
500
|
+
if (modelName) {
|
|
501
|
+
commands_1.push("MODEL NAME `".concat(modelName, "`"));
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
else if (taskType === 'SIMPLE_TASK') {
|
|
505
|
+
commands_1.push("SIMPLE TEMPLATE");
|
|
506
|
+
// Note: Nothing special here
|
|
507
|
+
}
|
|
508
|
+
else if (taskType === 'SCRIPT_TASK') {
|
|
509
|
+
commands_1.push("SCRIPT");
|
|
510
|
+
if (task.contentLanguage) {
|
|
511
|
+
contentLanguage = task.contentLanguage;
|
|
512
|
+
}
|
|
513
|
+
else {
|
|
514
|
+
contentLanguage = '';
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
else if (taskType === 'DIALOG_TASK') {
|
|
518
|
+
commands_1.push("DIALOG");
|
|
519
|
+
// Note: Nothing special here
|
|
520
|
+
} // <- }else if([🅱]
|
|
521
|
+
if (jokers) {
|
|
522
|
+
try {
|
|
523
|
+
for (var jokers_1 = (e_4 = void 0, __values(jokers)), jokers_1_1 = jokers_1.next(); !jokers_1_1.done; jokers_1_1 = jokers_1.next()) {
|
|
524
|
+
var joker = jokers_1_1.value;
|
|
525
|
+
commands_1.push("JOKER {".concat(joker, "}"));
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
529
|
+
finally {
|
|
530
|
+
try {
|
|
531
|
+
if (jokers_1_1 && !jokers_1_1.done && (_d = jokers_1.return)) _d.call(jokers_1);
|
|
532
|
+
}
|
|
533
|
+
finally { if (e_4) throw e_4.error; }
|
|
534
|
+
}
|
|
535
|
+
} /* not else */
|
|
536
|
+
if (postprocessing) {
|
|
537
|
+
try {
|
|
538
|
+
for (var postprocessing_1 = (e_5 = void 0, __values(postprocessing)), postprocessing_1_1 = postprocessing_1.next(); !postprocessing_1_1.done; postprocessing_1_1 = postprocessing_1.next()) {
|
|
539
|
+
var postprocessingFunctionName = postprocessing_1_1.value;
|
|
540
|
+
commands_1.push("POSTPROCESSING `".concat(postprocessingFunctionName, "`"));
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
544
|
+
finally {
|
|
545
|
+
try {
|
|
546
|
+
if (postprocessing_1_1 && !postprocessing_1_1.done && (_e = postprocessing_1.return)) _e.call(postprocessing_1);
|
|
547
|
+
}
|
|
548
|
+
finally { if (e_5) throw e_5.error; }
|
|
549
|
+
}
|
|
550
|
+
} /* not else */
|
|
551
|
+
if (expectations) {
|
|
552
|
+
try {
|
|
553
|
+
for (var _m = (e_6 = void 0, __values(Object.entries(expectations))), _o = _m.next(); !_o.done; _o = _m.next()) {
|
|
554
|
+
var _p = __read(_o.value, 2), unit = _p[0], _q = _p[1], min = _q.min, max = _q.max;
|
|
555
|
+
if (min === max) {
|
|
556
|
+
commands_1.push("EXPECT EXACTLY ".concat(min, " ").concat(capitalize(unit + (min > 1 ? 's' : ''))));
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
if (min !== undefined) {
|
|
560
|
+
commands_1.push("EXPECT MIN ".concat(min, " ").concat(capitalize(unit + (min > 1 ? 's' : ''))));
|
|
561
|
+
} /* not else */
|
|
562
|
+
if (max !== undefined) {
|
|
563
|
+
commands_1.push("EXPECT MAX ".concat(max, " ").concat(capitalize(unit + (max > 1 ? 's' : ''))));
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
569
|
+
finally {
|
|
570
|
+
try {
|
|
571
|
+
if (_o && !_o.done && (_f = _m.return)) _f.call(_m);
|
|
572
|
+
}
|
|
573
|
+
finally { if (e_6) throw e_6.error; }
|
|
574
|
+
}
|
|
575
|
+
} /* not else */
|
|
576
|
+
if (format) {
|
|
577
|
+
if (format === 'JSON') {
|
|
578
|
+
// TODO: @deprecated remove
|
|
579
|
+
commands_1.push("FORMAT JSON");
|
|
580
|
+
}
|
|
581
|
+
} /* not else */
|
|
582
|
+
pipelineString += '\n\n';
|
|
583
|
+
pipelineString += commands_1.map(function (command) { return "- ".concat(command); }).join('\n');
|
|
584
|
+
pipelineString += '\n\n';
|
|
585
|
+
pipelineString += '```' + contentLanguage;
|
|
586
|
+
pipelineString += '\n';
|
|
587
|
+
pipelineString += spaceTrim(content);
|
|
588
|
+
// <- TODO: [main] !!3 Escape
|
|
589
|
+
// <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
|
|
590
|
+
pipelineString += '\n';
|
|
591
|
+
pipelineString += '```';
|
|
592
|
+
pipelineString += '\n\n';
|
|
593
|
+
pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: [main] !!3 If the parameter here has description, add it and use taskParameterJsonToString
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
597
|
+
finally {
|
|
598
|
+
try {
|
|
599
|
+
if (tasks_1_1 && !tasks_1_1.done && (_c = tasks_1.return)) _c.call(tasks_1);
|
|
600
|
+
}
|
|
601
|
+
finally { if (e_3) throw e_3.error; }
|
|
602
|
+
}
|
|
603
|
+
return validatePipelineString(pipelineString);
|
|
573
604
|
}
|
|
574
605
|
/**
|
|
575
|
-
*
|
|
606
|
+
* @private internal utility of `pipelineJsonToString`
|
|
576
607
|
*/
|
|
577
|
-
|
|
608
|
+
function taskParameterJsonToString(taskParameterJson) {
|
|
609
|
+
var name = taskParameterJson.name, description = taskParameterJson.description;
|
|
610
|
+
var parameterString = "{".concat(name, "}");
|
|
611
|
+
if (description) {
|
|
612
|
+
parameterString = "".concat(parameterString, " ").concat(description);
|
|
613
|
+
}
|
|
614
|
+
return parameterString;
|
|
615
|
+
}
|
|
578
616
|
/**
|
|
579
|
-
*
|
|
580
|
-
*
|
|
581
|
-
*
|
|
617
|
+
* TODO: [🛋] Implement new features and commands into `pipelineJsonToString` + `taskParameterJsonToString` , use `stringifyCommand`
|
|
618
|
+
* TODO: [🧠] Is there a way to auto-detect missing features in pipelineJsonToString
|
|
619
|
+
* TODO: [🏛] Maybe make some markdown builder
|
|
620
|
+
* TODO: [🏛] Escape all
|
|
621
|
+
* TODO: [🧠] Should be in generated .book.md file GENERATOR_WARNING
|
|
582
622
|
*/
|
|
583
|
-
|
|
584
|
-
// Note: [🍙] In this order will be pipeline serialized
|
|
585
|
-
'title',
|
|
586
|
-
'pipelineUrl',
|
|
587
|
-
'bookVersion',
|
|
588
|
-
'description',
|
|
589
|
-
'formfactorName',
|
|
590
|
-
'parameters',
|
|
591
|
-
'tasks',
|
|
592
|
-
'personas',
|
|
593
|
-
'preparations',
|
|
594
|
-
'knowledgeSources',
|
|
595
|
-
'knowledgePieces',
|
|
596
|
-
'sources', // <- TODO: [🧠] Where should the `sources` be
|
|
597
|
-
];
|
|
623
|
+
|
|
598
624
|
/**
|
|
599
|
-
*
|
|
625
|
+
* Orders JSON object by keys
|
|
600
626
|
*
|
|
601
|
-
* @
|
|
627
|
+
* @returns The same type of object as the input re-ordered
|
|
628
|
+
* @public exported from `@promptbook/utils`
|
|
602
629
|
*/
|
|
603
|
-
|
|
630
|
+
function orderJson(options) {
|
|
631
|
+
var value = options.value, order = options.order;
|
|
632
|
+
var orderedValue = __assign(__assign({}, (order === undefined ? {} : Object.fromEntries(order.map(function (key) { return [key, undefined]; })))), value);
|
|
633
|
+
return orderedValue;
|
|
634
|
+
}
|
|
635
|
+
|
|
604
636
|
/**
|
|
605
|
-
*
|
|
637
|
+
* Freezes the given object and all its nested objects recursively
|
|
606
638
|
*
|
|
607
|
-
*
|
|
608
|
-
|
|
609
|
-
var RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
|
|
610
|
-
/**
|
|
611
|
-
* @@@
|
|
639
|
+
* Note: `$` is used to indicate that this function is not a pure function - it mutates given object
|
|
640
|
+
* Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
|
|
612
641
|
*
|
|
613
|
-
* @
|
|
642
|
+
* @returns The same object as the input, but deeply frozen
|
|
643
|
+
* @public exported from `@promptbook/utils`
|
|
614
644
|
*/
|
|
615
|
-
|
|
645
|
+
function $deepFreeze(objectValue) {
|
|
646
|
+
var e_1, _a;
|
|
647
|
+
if (Array.isArray(objectValue)) {
|
|
648
|
+
return Object.freeze(objectValue.map(function (item) { return $deepFreeze(item); }));
|
|
649
|
+
}
|
|
650
|
+
var propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
651
|
+
try {
|
|
652
|
+
for (var propertyNames_1 = __values(propertyNames), propertyNames_1_1 = propertyNames_1.next(); !propertyNames_1_1.done; propertyNames_1_1 = propertyNames_1.next()) {
|
|
653
|
+
var propertyName = propertyNames_1_1.value;
|
|
654
|
+
var value = objectValue[propertyName];
|
|
655
|
+
if (value && typeof value === 'object') {
|
|
656
|
+
$deepFreeze(value);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
661
|
+
finally {
|
|
662
|
+
try {
|
|
663
|
+
if (propertyNames_1_1 && !propertyNames_1_1.done && (_a = propertyNames_1.return)) _a.call(propertyNames_1);
|
|
664
|
+
}
|
|
665
|
+
finally { if (e_1) throw e_1.error; }
|
|
666
|
+
}
|
|
667
|
+
Object.freeze(objectValue);
|
|
668
|
+
return objectValue;
|
|
669
|
+
}
|
|
616
670
|
/**
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
* @public exported from `@promptbook/core`
|
|
671
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
620
672
|
*/
|
|
621
|
-
|
|
622
|
-
name: 'RESERVED_PARAMETER_NAMES',
|
|
623
|
-
message: "The names of the parameters that are reserved for special purposes",
|
|
624
|
-
value: [
|
|
625
|
-
'content',
|
|
626
|
-
'context',
|
|
627
|
-
'knowledge',
|
|
628
|
-
'examples',
|
|
629
|
-
'modelName',
|
|
630
|
-
'currentDate',
|
|
631
|
-
// <- TODO: list here all command names
|
|
632
|
-
// <- TODO: Add more like 'date', 'modelName',...
|
|
633
|
-
// <- TODO: Add [emoji] + instructions ACRY when adding new reserved parameter
|
|
634
|
-
],
|
|
635
|
-
});
|
|
673
|
+
|
|
636
674
|
/**
|
|
637
|
-
*
|
|
675
|
+
* Make error report URL for the given error
|
|
676
|
+
*
|
|
677
|
+
* @private private within the repository
|
|
638
678
|
*/
|
|
679
|
+
function getErrorReportUrl(error) {
|
|
680
|
+
var report = {
|
|
681
|
+
title: "\uD83D\uDC1C Error report from ".concat(NAME),
|
|
682
|
+
body: spaceTrim(function (block) { return "\n\n\n `".concat(error.name || 'Error', "` has occurred in the [").concat(NAME, "], please look into it @").concat(ADMIN_GITHUB_NAME, ".\n\n ```\n ").concat(block(error.message || '(no error message)'), "\n ```\n\n\n ## More info:\n\n - **Promptbook engine version:** ").concat(PROMPTBOOK_ENGINE_VERSION, "\n - **Book language version:** ").concat(BOOK_LANGUAGE_VERSION, "\n - **Time:** ").concat(new Date().toISOString(), "\n\n <details>\n <summary>Stack trace:</summary>\n\n ## Stack trace:\n\n ```stacktrace\n ").concat(block(error.stack || '(empty)'), "\n ```\n </details>\n\n "); }),
|
|
683
|
+
};
|
|
684
|
+
var reportUrl = new URL("https://github.com/webgptorg/promptbook/issues/new");
|
|
685
|
+
reportUrl.searchParams.set('labels', 'bug');
|
|
686
|
+
reportUrl.searchParams.set('assignees', ADMIN_GITHUB_NAME);
|
|
687
|
+
reportUrl.searchParams.set('title', report.title);
|
|
688
|
+
reportUrl.searchParams.set('body', report.body);
|
|
689
|
+
return reportUrl;
|
|
690
|
+
}
|
|
639
691
|
|
|
640
692
|
/**
|
|
641
|
-
* This error type indicates that
|
|
693
|
+
* This error type indicates that the error should not happen and its last check before crashing with some other error
|
|
642
694
|
*
|
|
643
695
|
* @public exported from `@promptbook/core`
|
|
644
696
|
*/
|
|
645
|
-
var
|
|
646
|
-
__extends(
|
|
647
|
-
function
|
|
648
|
-
var _this = _super.call(this, spaceTrim$1(function (block) { return "\n ".concat(block(message), "\n\n Note:
|
|
649
|
-
_this.name = '
|
|
650
|
-
Object.setPrototypeOf(_this,
|
|
697
|
+
var UnexpectedError = /** @class */ (function (_super) {
|
|
698
|
+
__extends(UnexpectedError, _super);
|
|
699
|
+
function UnexpectedError(message) {
|
|
700
|
+
var _this = _super.call(this, spaceTrim$1(function (block) { return "\n ".concat(block(message), "\n\n Note: This error should not happen.\n It's probbably a bug in the pipeline collection\n\n Please report issue:\n ").concat(block(getErrorReportUrl(new Error(message)).href), "\n\n Or contact us on ").concat(ADMIN_EMAIL, "\n\n "); })) || this;
|
|
701
|
+
_this.name = 'UnexpectedError';
|
|
702
|
+
Object.setPrototypeOf(_this, UnexpectedError.prototype);
|
|
651
703
|
return _this;
|
|
652
704
|
}
|
|
653
|
-
return
|
|
705
|
+
return UnexpectedError;
|
|
654
706
|
}(Error));
|
|
655
707
|
|
|
656
708
|
/**
|
|
657
|
-
*
|
|
709
|
+
* Checks if the value is [🚉] serializable as JSON
|
|
710
|
+
* If not, throws an UnexpectedError with a rich error message and tracking
|
|
658
711
|
*
|
|
659
|
-
*
|
|
660
|
-
*
|
|
661
|
-
*
|
|
712
|
+
* - Almost all primitives are serializable BUT:
|
|
713
|
+
* - `undefined` is not serializable
|
|
714
|
+
* - `NaN` is not serializable
|
|
715
|
+
* - Objects and arrays are serializable if all their properties are serializable
|
|
716
|
+
* - Functions are not serializable
|
|
717
|
+
* - Circular references are not serializable
|
|
718
|
+
* - `Date` objects are not serializable
|
|
719
|
+
* - `Map` and `Set` objects are not serializable
|
|
720
|
+
* - `RegExp` objects are not serializable
|
|
721
|
+
* - `Error` objects are not serializable
|
|
722
|
+
* - `Symbol` objects are not serializable
|
|
723
|
+
* - And much more...
|
|
724
|
+
*
|
|
725
|
+
* @throws UnexpectedError if the value is not serializable as JSON
|
|
662
726
|
* @public exported from `@promptbook/utils`
|
|
663
|
-
* @deprecated [🪂] Use queues instead
|
|
664
727
|
*/
|
|
665
|
-
function
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
};
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
case 7:
|
|
718
|
-
try {
|
|
719
|
-
if (_c && !_c.done && (_d = _b.return)) _d.call(_b);
|
|
728
|
+
function checkSerializableAsJson(options) {
|
|
729
|
+
var e_1, _a;
|
|
730
|
+
var value = options.value, name = options.name, message = options.message;
|
|
731
|
+
if (value === undefined) {
|
|
732
|
+
throw new UnexpectedError("".concat(name, " is undefined"));
|
|
733
|
+
}
|
|
734
|
+
else if (value === null) {
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
else if (typeof value === 'boolean') {
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
else if (typeof value === 'number' && !isNaN(value)) {
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
else if (typeof value === 'string') {
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
else if (typeof value === 'symbol') {
|
|
747
|
+
throw new UnexpectedError("".concat(name, " is symbol"));
|
|
748
|
+
}
|
|
749
|
+
else if (typeof value === 'function') {
|
|
750
|
+
throw new UnexpectedError("".concat(name, " is function"));
|
|
751
|
+
}
|
|
752
|
+
else if (typeof value === 'object' && Array.isArray(value)) {
|
|
753
|
+
for (var i = 0; i < value.length; i++) {
|
|
754
|
+
checkSerializableAsJson({ name: "".concat(name, "[").concat(i, "]"), value: value[i], message: message });
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
else if (typeof value === 'object') {
|
|
758
|
+
if (value instanceof Date) {
|
|
759
|
+
throw new UnexpectedError(spaceTrim(function (block) { return "\n `".concat(name, "` is Date\n\n Use `string_date_iso8601` instead\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n "); }));
|
|
760
|
+
}
|
|
761
|
+
else if (value instanceof Map) {
|
|
762
|
+
throw new UnexpectedError("".concat(name, " is Map"));
|
|
763
|
+
}
|
|
764
|
+
else if (value instanceof Set) {
|
|
765
|
+
throw new UnexpectedError("".concat(name, " is Set"));
|
|
766
|
+
}
|
|
767
|
+
else if (value instanceof RegExp) {
|
|
768
|
+
throw new UnexpectedError("".concat(name, " is RegExp"));
|
|
769
|
+
}
|
|
770
|
+
else if (value instanceof Error) {
|
|
771
|
+
throw new UnexpectedError(spaceTrim(function (block) { return "\n `".concat(name, "` is unserialized Error\n\n Use function `serializeError`\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n\n "); }));
|
|
772
|
+
}
|
|
773
|
+
else {
|
|
774
|
+
try {
|
|
775
|
+
for (var _b = __values(Object.entries(value)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
776
|
+
var _d = __read(_c.value, 2), subName = _d[0], subValue = _d[1];
|
|
777
|
+
if (subValue === undefined) {
|
|
778
|
+
// Note: undefined in object is serializable - it is just omited
|
|
779
|
+
continue;
|
|
720
780
|
}
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
case 8: return [4 /*yield*/, Promise.all(tasks)];
|
|
724
|
-
case 9:
|
|
725
|
-
_e.sent();
|
|
726
|
-
return [2 /*return*/];
|
|
781
|
+
checkSerializableAsJson({ name: "".concat(name, ".").concat(subName), value: subValue, message: message });
|
|
782
|
+
}
|
|
727
783
|
}
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
/**
|
|
733
|
-
* Represents the usage with no resources consumed
|
|
734
|
-
*
|
|
735
|
-
* @public exported from `@promptbook/core`
|
|
736
|
-
*/
|
|
737
|
-
var ZERO_USAGE = $deepFreeze({
|
|
738
|
-
price: { value: 0 },
|
|
739
|
-
input: {
|
|
740
|
-
tokensCount: { value: 0 },
|
|
741
|
-
charactersCount: { value: 0 },
|
|
742
|
-
wordsCount: { value: 0 },
|
|
743
|
-
sentencesCount: { value: 0 },
|
|
744
|
-
linesCount: { value: 0 },
|
|
745
|
-
paragraphsCount: { value: 0 },
|
|
746
|
-
pagesCount: { value: 0 },
|
|
747
|
-
},
|
|
748
|
-
output: {
|
|
749
|
-
tokensCount: { value: 0 },
|
|
750
|
-
charactersCount: { value: 0 },
|
|
751
|
-
wordsCount: { value: 0 },
|
|
752
|
-
sentencesCount: { value: 0 },
|
|
753
|
-
linesCount: { value: 0 },
|
|
754
|
-
paragraphsCount: { value: 0 },
|
|
755
|
-
pagesCount: { value: 0 },
|
|
756
|
-
},
|
|
757
|
-
});
|
|
758
|
-
/**
|
|
759
|
-
* Represents the usage with unknown resources consumed
|
|
760
|
-
*
|
|
761
|
-
* @public exported from `@promptbook/core`
|
|
762
|
-
*/
|
|
763
|
-
$deepFreeze({
|
|
764
|
-
price: { value: 0, isUncertain: true },
|
|
765
|
-
input: {
|
|
766
|
-
tokensCount: { value: 0, isUncertain: true },
|
|
767
|
-
charactersCount: { value: 0, isUncertain: true },
|
|
768
|
-
wordsCount: { value: 0, isUncertain: true },
|
|
769
|
-
sentencesCount: { value: 0, isUncertain: true },
|
|
770
|
-
linesCount: { value: 0, isUncertain: true },
|
|
771
|
-
paragraphsCount: { value: 0, isUncertain: true },
|
|
772
|
-
pagesCount: { value: 0, isUncertain: true },
|
|
773
|
-
},
|
|
774
|
-
output: {
|
|
775
|
-
tokensCount: { value: 0, isUncertain: true },
|
|
776
|
-
charactersCount: { value: 0, isUncertain: true },
|
|
777
|
-
wordsCount: { value: 0, isUncertain: true },
|
|
778
|
-
sentencesCount: { value: 0, isUncertain: true },
|
|
779
|
-
linesCount: { value: 0, isUncertain: true },
|
|
780
|
-
paragraphsCount: { value: 0, isUncertain: true },
|
|
781
|
-
pagesCount: { value: 0, isUncertain: true },
|
|
782
|
-
},
|
|
783
|
-
});
|
|
784
|
-
/**
|
|
785
|
-
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
786
|
-
*/
|
|
787
|
-
|
|
788
|
-
/**
|
|
789
|
-
* Function `addUsage` will add multiple usages into one
|
|
790
|
-
*
|
|
791
|
-
* Note: If you provide 0 values, it returns ZERO_USAGE
|
|
792
|
-
*
|
|
793
|
-
* @public exported from `@promptbook/core`
|
|
794
|
-
*/
|
|
795
|
-
function addUsage() {
|
|
796
|
-
var usageItems = [];
|
|
797
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
798
|
-
usageItems[_i] = arguments[_i];
|
|
799
|
-
}
|
|
800
|
-
return usageItems.reduce(function (acc, item) {
|
|
801
|
-
var e_1, _a, e_2, _b;
|
|
802
|
-
var _c;
|
|
803
|
-
acc.price.value += ((_c = item.price) === null || _c === void 0 ? void 0 : _c.value) || 0;
|
|
804
|
-
try {
|
|
805
|
-
for (var _d = __values(Object.keys(acc.input)), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
806
|
-
var key = _e.value;
|
|
807
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
808
|
-
//@ts-ignore
|
|
809
|
-
if (item.input[key]) {
|
|
810
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
811
|
-
//@ts-ignore
|
|
812
|
-
acc.input[key].value += item.input[key].value || 0;
|
|
813
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
814
|
-
//@ts-ignore
|
|
815
|
-
if (item.input[key].isUncertain) {
|
|
816
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
817
|
-
//@ts-ignore
|
|
818
|
-
acc.input[key].isUncertain = true;
|
|
819
|
-
}
|
|
784
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
785
|
+
finally {
|
|
786
|
+
try {
|
|
787
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
820
788
|
}
|
|
789
|
+
finally { if (e_1) throw e_1.error; }
|
|
821
790
|
}
|
|
822
|
-
}
|
|
823
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
824
|
-
finally {
|
|
825
791
|
try {
|
|
826
|
-
|
|
792
|
+
JSON.stringify(value); // <- TODO: [0]
|
|
827
793
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
for (var _f = __values(Object.keys(acc.output)), _g = _f.next(); !_g.done; _g = _f.next()) {
|
|
832
|
-
var key = _g.value;
|
|
833
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
834
|
-
//@ts-ignore
|
|
835
|
-
if (item.output[key]) {
|
|
836
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
837
|
-
//@ts-ignore
|
|
838
|
-
acc.output[key].value += item.output[key].value || 0;
|
|
839
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
840
|
-
//@ts-ignore
|
|
841
|
-
if (item.output[key].isUncertain) {
|
|
842
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
843
|
-
//@ts-ignore
|
|
844
|
-
acc.output[key].isUncertain = true;
|
|
845
|
-
}
|
|
794
|
+
catch (error) {
|
|
795
|
+
if (!(error instanceof Error)) {
|
|
796
|
+
throw error;
|
|
846
797
|
}
|
|
798
|
+
throw new UnexpectedError(spaceTrim(function (block) { return "\n `".concat(name, "` is not serializable\n\n ").concat(block(error.stack || error.message), "\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n "); }));
|
|
847
799
|
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
800
|
+
/*
|
|
801
|
+
TODO: [0] Is there some more elegant way to check circular references?
|
|
802
|
+
const seen = new Set();
|
|
803
|
+
const stack = [{ value }];
|
|
804
|
+
while (stack.length > 0) {
|
|
805
|
+
const { value } = stack.pop()!;
|
|
806
|
+
if (typeof value === 'object' && value !== null) {
|
|
807
|
+
if (seen.has(value)) {
|
|
808
|
+
throw new UnexpectedError(`${name} has circular reference`);
|
|
809
|
+
}
|
|
810
|
+
seen.add(value);
|
|
811
|
+
if (Array.isArray(value)) {
|
|
812
|
+
stack.push(...value.map((value) => ({ value })));
|
|
813
|
+
} else {
|
|
814
|
+
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
815
|
+
}
|
|
816
|
+
}
|
|
853
817
|
}
|
|
854
|
-
|
|
818
|
+
*/
|
|
819
|
+
return;
|
|
855
820
|
}
|
|
856
|
-
return acc;
|
|
857
|
-
}, deepClone(ZERO_USAGE));
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
/**
|
|
861
|
-
* Intercepts LLM tools and counts total usage of the tools
|
|
862
|
-
*
|
|
863
|
-
* @param llmTools LLM tools to be intercepted with usage counting
|
|
864
|
-
* @returns LLM tools with same functionality with added total cost counting
|
|
865
|
-
* @public exported from `@promptbook/core`
|
|
866
|
-
*/
|
|
867
|
-
function countTotalUsage(llmTools) {
|
|
868
|
-
var _this = this;
|
|
869
|
-
var totalUsage = ZERO_USAGE;
|
|
870
|
-
var proxyTools = {
|
|
871
|
-
get title() {
|
|
872
|
-
// TODO: [🧠] Maybe put here some suffix
|
|
873
|
-
return llmTools.title;
|
|
874
|
-
},
|
|
875
|
-
get description() {
|
|
876
|
-
// TODO: [🧠] Maybe put here some suffix
|
|
877
|
-
return llmTools.description;
|
|
878
|
-
},
|
|
879
|
-
checkConfiguration: function () {
|
|
880
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
881
|
-
return __generator(this, function (_a) {
|
|
882
|
-
return [2 /*return*/, /* not await */ llmTools.checkConfiguration()];
|
|
883
|
-
});
|
|
884
|
-
});
|
|
885
|
-
},
|
|
886
|
-
listModels: function () {
|
|
887
|
-
return /* not await */ llmTools.listModels();
|
|
888
|
-
},
|
|
889
|
-
getTotalUsage: function () {
|
|
890
|
-
// <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
|
|
891
|
-
return totalUsage;
|
|
892
|
-
},
|
|
893
|
-
};
|
|
894
|
-
if (llmTools.callChatModel !== undefined) {
|
|
895
|
-
proxyTools.callChatModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
|
|
896
|
-
var promptResult;
|
|
897
|
-
return __generator(this, function (_a) {
|
|
898
|
-
switch (_a.label) {
|
|
899
|
-
case 0: return [4 /*yield*/, llmTools.callChatModel(prompt)];
|
|
900
|
-
case 1:
|
|
901
|
-
promptResult = _a.sent();
|
|
902
|
-
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
903
|
-
return [2 /*return*/, promptResult];
|
|
904
|
-
}
|
|
905
|
-
});
|
|
906
|
-
}); };
|
|
907
|
-
}
|
|
908
|
-
if (llmTools.callCompletionModel !== undefined) {
|
|
909
|
-
proxyTools.callCompletionModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
|
|
910
|
-
var promptResult;
|
|
911
|
-
return __generator(this, function (_a) {
|
|
912
|
-
switch (_a.label) {
|
|
913
|
-
case 0: return [4 /*yield*/, llmTools.callCompletionModel(prompt)];
|
|
914
|
-
case 1:
|
|
915
|
-
promptResult = _a.sent();
|
|
916
|
-
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
917
|
-
return [2 /*return*/, promptResult];
|
|
918
|
-
}
|
|
919
|
-
});
|
|
920
|
-
}); };
|
|
921
821
|
}
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
var promptResult;
|
|
925
|
-
return __generator(this, function (_a) {
|
|
926
|
-
switch (_a.label) {
|
|
927
|
-
case 0: return [4 /*yield*/, llmTools.callEmbeddingModel(prompt)];
|
|
928
|
-
case 1:
|
|
929
|
-
promptResult = _a.sent();
|
|
930
|
-
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
931
|
-
return [2 /*return*/, promptResult];
|
|
932
|
-
}
|
|
933
|
-
});
|
|
934
|
-
}); };
|
|
822
|
+
else {
|
|
823
|
+
throw new UnexpectedError(spaceTrim(function (block) { return "\n `".concat(name, "` is unknown type\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n "); }));
|
|
935
824
|
}
|
|
936
|
-
// <- Note: [🤖]
|
|
937
|
-
return proxyTools;
|
|
938
825
|
}
|
|
939
826
|
/**
|
|
940
|
-
* TODO:
|
|
941
|
-
* TODO: [🧠]
|
|
942
|
-
*
|
|
943
|
-
* > const [llmToolsWithUsage,getUsage] = countTotalUsage(llmTools);
|
|
944
|
-
* TODO: [👷♂️] @@@ Manual about construction of llmTools
|
|
827
|
+
* TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
828
|
+
* TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
829
|
+
* Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
945
830
|
*/
|
|
946
831
|
|
|
947
832
|
/**
|
|
948
|
-
*
|
|
833
|
+
* @@@
|
|
949
834
|
*
|
|
950
|
-
* @public exported from `@promptbook/
|
|
835
|
+
* @public exported from `@promptbook/utils`
|
|
836
|
+
*/
|
|
837
|
+
function deepClone(objectValue) {
|
|
838
|
+
return JSON.parse(JSON.stringify(objectValue));
|
|
839
|
+
/*
|
|
840
|
+
TODO: [🧠] Is there a better implementation?
|
|
841
|
+
> const propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
842
|
+
> for (const propertyName of propertyNames) {
|
|
843
|
+
> const value = (objectValue as really_any)[propertyName];
|
|
844
|
+
> if (value && typeof value === 'object') {
|
|
845
|
+
> deepClone(value);
|
|
846
|
+
> }
|
|
847
|
+
> }
|
|
848
|
+
> return Object.assign({}, objectValue);
|
|
849
|
+
*/
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
951
853
|
*/
|
|
952
|
-
var PipelineExecutionError = /** @class */ (function (_super) {
|
|
953
|
-
__extends(PipelineExecutionError, _super);
|
|
954
|
-
function PipelineExecutionError(message) {
|
|
955
|
-
var _this = _super.call(this, message) || this;
|
|
956
|
-
_this.name = 'PipelineExecutionError';
|
|
957
|
-
Object.setPrototypeOf(_this, PipelineExecutionError.prototype);
|
|
958
|
-
return _this;
|
|
959
|
-
}
|
|
960
|
-
return PipelineExecutionError;
|
|
961
|
-
}(Error));
|
|
962
854
|
|
|
963
855
|
/**
|
|
964
|
-
*
|
|
856
|
+
* Utility to export a JSON object from a function
|
|
965
857
|
*
|
|
966
|
-
*
|
|
967
|
-
*
|
|
858
|
+
* 1) Checks if the value is serializable as JSON
|
|
859
|
+
* 2) Makes a deep clone of the object
|
|
860
|
+
* 2) Orders the object properties
|
|
861
|
+
* 2) Deeply freezes the cloned object
|
|
862
|
+
*
|
|
863
|
+
* Note: This function does not mutates the given object
|
|
864
|
+
*
|
|
865
|
+
* @returns The same type of object as the input but read-only and re-ordered
|
|
866
|
+
* @public exported from `@promptbook/utils`
|
|
968
867
|
*/
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
return 'Multiple LLM Providers';
|
|
983
|
-
},
|
|
984
|
-
enumerable: false,
|
|
985
|
-
configurable: true
|
|
986
|
-
});
|
|
987
|
-
Object.defineProperty(MultipleLlmExecutionTools.prototype, "description", {
|
|
988
|
-
get: function () {
|
|
989
|
-
return this.llmExecutionTools.map(function (_a, index) {
|
|
990
|
-
var title = _a.title;
|
|
991
|
-
return "".concat(index + 1, ") `").concat(title, "`");
|
|
992
|
-
}).join('\n');
|
|
993
|
-
},
|
|
994
|
-
enumerable: false,
|
|
995
|
-
configurable: true
|
|
996
|
-
});
|
|
997
|
-
/**
|
|
998
|
-
* Check the configuration of all execution tools
|
|
999
|
-
*/
|
|
1000
|
-
MultipleLlmExecutionTools.prototype.checkConfiguration = function () {
|
|
1001
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1002
|
-
var _a, _b, llmExecutionTools, e_1_1;
|
|
1003
|
-
var e_1, _c;
|
|
1004
|
-
return __generator(this, function (_d) {
|
|
1005
|
-
switch (_d.label) {
|
|
1006
|
-
case 0:
|
|
1007
|
-
_d.trys.push([0, 5, 6, 7]);
|
|
1008
|
-
_a = __values(this.llmExecutionTools), _b = _a.next();
|
|
1009
|
-
_d.label = 1;
|
|
1010
|
-
case 1:
|
|
1011
|
-
if (!!_b.done) return [3 /*break*/, 4];
|
|
1012
|
-
llmExecutionTools = _b.value;
|
|
1013
|
-
return [4 /*yield*/, llmExecutionTools.checkConfiguration()];
|
|
1014
|
-
case 2:
|
|
1015
|
-
_d.sent();
|
|
1016
|
-
_d.label = 3;
|
|
1017
|
-
case 3:
|
|
1018
|
-
_b = _a.next();
|
|
1019
|
-
return [3 /*break*/, 1];
|
|
1020
|
-
case 4: return [3 /*break*/, 7];
|
|
1021
|
-
case 5:
|
|
1022
|
-
e_1_1 = _d.sent();
|
|
1023
|
-
e_1 = { error: e_1_1 };
|
|
1024
|
-
return [3 /*break*/, 7];
|
|
1025
|
-
case 6:
|
|
1026
|
-
try {
|
|
1027
|
-
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
1028
|
-
}
|
|
1029
|
-
finally { if (e_1) throw e_1.error; }
|
|
1030
|
-
return [7 /*endfinally*/];
|
|
1031
|
-
case 7: return [2 /*return*/];
|
|
1032
|
-
}
|
|
1033
|
-
});
|
|
1034
|
-
});
|
|
1035
|
-
};
|
|
1036
|
-
/**
|
|
1037
|
-
* List all available models that can be used
|
|
1038
|
-
* This lists is a combination of all available models from all execution tools
|
|
1039
|
-
*/
|
|
1040
|
-
MultipleLlmExecutionTools.prototype.listModels = function () {
|
|
1041
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1042
|
-
var availableModels, _a, _b, llmExecutionTools, models, e_2_1;
|
|
1043
|
-
var e_2, _c;
|
|
1044
|
-
return __generator(this, function (_d) {
|
|
1045
|
-
switch (_d.label) {
|
|
1046
|
-
case 0:
|
|
1047
|
-
availableModels = [];
|
|
1048
|
-
_d.label = 1;
|
|
1049
|
-
case 1:
|
|
1050
|
-
_d.trys.push([1, 6, 7, 8]);
|
|
1051
|
-
_a = __values(this.llmExecutionTools), _b = _a.next();
|
|
1052
|
-
_d.label = 2;
|
|
1053
|
-
case 2:
|
|
1054
|
-
if (!!_b.done) return [3 /*break*/, 5];
|
|
1055
|
-
llmExecutionTools = _b.value;
|
|
1056
|
-
return [4 /*yield*/, llmExecutionTools.listModels()];
|
|
1057
|
-
case 3:
|
|
1058
|
-
models = _d.sent();
|
|
1059
|
-
availableModels.push.apply(availableModels, __spreadArray([], __read(models), false));
|
|
1060
|
-
_d.label = 4;
|
|
1061
|
-
case 4:
|
|
1062
|
-
_b = _a.next();
|
|
1063
|
-
return [3 /*break*/, 2];
|
|
1064
|
-
case 5: return [3 /*break*/, 8];
|
|
1065
|
-
case 6:
|
|
1066
|
-
e_2_1 = _d.sent();
|
|
1067
|
-
e_2 = { error: e_2_1 };
|
|
1068
|
-
return [3 /*break*/, 8];
|
|
1069
|
-
case 7:
|
|
1070
|
-
try {
|
|
1071
|
-
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
1072
|
-
}
|
|
1073
|
-
finally { if (e_2) throw e_2.error; }
|
|
1074
|
-
return [7 /*endfinally*/];
|
|
1075
|
-
case 8: return [2 /*return*/, availableModels];
|
|
1076
|
-
}
|
|
1077
|
-
});
|
|
1078
|
-
});
|
|
1079
|
-
};
|
|
1080
|
-
/**
|
|
1081
|
-
* Calls the best available chat model
|
|
1082
|
-
*/
|
|
1083
|
-
MultipleLlmExecutionTools.prototype.callChatModel = function (prompt) {
|
|
1084
|
-
return this.callCommonModel(prompt);
|
|
1085
|
-
};
|
|
1086
|
-
/**
|
|
1087
|
-
* Calls the best available completion model
|
|
1088
|
-
*/
|
|
1089
|
-
MultipleLlmExecutionTools.prototype.callCompletionModel = function (prompt) {
|
|
1090
|
-
return this.callCommonModel(prompt);
|
|
1091
|
-
};
|
|
1092
|
-
/**
|
|
1093
|
-
* Calls the best available embedding model
|
|
1094
|
-
*/
|
|
1095
|
-
MultipleLlmExecutionTools.prototype.callEmbeddingModel = function (prompt) {
|
|
1096
|
-
return this.callCommonModel(prompt);
|
|
1097
|
-
};
|
|
1098
|
-
// <- Note: [🤖]
|
|
1099
|
-
/**
|
|
1100
|
-
* Calls the best available model
|
|
1101
|
-
*
|
|
1102
|
-
* Note: This should be private or protected but is public to be usable with duck typing
|
|
1103
|
-
*/
|
|
1104
|
-
MultipleLlmExecutionTools.prototype.callCommonModel = function (prompt) {
|
|
1105
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1106
|
-
var errors, _a, _b, llmExecutionTools, _c, error_1, e_3_1;
|
|
1107
|
-
var e_3, _d;
|
|
1108
|
-
var _this = this;
|
|
1109
|
-
return __generator(this, function (_e) {
|
|
1110
|
-
switch (_e.label) {
|
|
1111
|
-
case 0:
|
|
1112
|
-
errors = [];
|
|
1113
|
-
_e.label = 1;
|
|
1114
|
-
case 1:
|
|
1115
|
-
_e.trys.push([1, 15, 16, 17]);
|
|
1116
|
-
_a = __values(this.llmExecutionTools), _b = _a.next();
|
|
1117
|
-
_e.label = 2;
|
|
1118
|
-
case 2:
|
|
1119
|
-
if (!!_b.done) return [3 /*break*/, 14];
|
|
1120
|
-
llmExecutionTools = _b.value;
|
|
1121
|
-
_e.label = 3;
|
|
1122
|
-
case 3:
|
|
1123
|
-
_e.trys.push([3, 12, , 13]);
|
|
1124
|
-
_c = prompt.modelRequirements.modelVariant;
|
|
1125
|
-
switch (_c) {
|
|
1126
|
-
case 'CHAT': return [3 /*break*/, 4];
|
|
1127
|
-
case 'COMPLETION': return [3 /*break*/, 6];
|
|
1128
|
-
case 'EMBEDDING': return [3 /*break*/, 8];
|
|
1129
|
-
}
|
|
1130
|
-
return [3 /*break*/, 10];
|
|
1131
|
-
case 4:
|
|
1132
|
-
if (llmExecutionTools.callChatModel === undefined) {
|
|
1133
|
-
return [3 /*break*/, 13];
|
|
1134
|
-
}
|
|
1135
|
-
return [4 /*yield*/, llmExecutionTools.callChatModel(prompt)];
|
|
1136
|
-
case 5: return [2 /*return*/, _e.sent()];
|
|
1137
|
-
case 6:
|
|
1138
|
-
if (llmExecutionTools.callCompletionModel === undefined) {
|
|
1139
|
-
return [3 /*break*/, 13];
|
|
1140
|
-
}
|
|
1141
|
-
return [4 /*yield*/, llmExecutionTools.callCompletionModel(prompt)];
|
|
1142
|
-
case 7: return [2 /*return*/, _e.sent()];
|
|
1143
|
-
case 8:
|
|
1144
|
-
if (llmExecutionTools.callEmbeddingModel === undefined) {
|
|
1145
|
-
return [3 /*break*/, 13];
|
|
1146
|
-
}
|
|
1147
|
-
return [4 /*yield*/, llmExecutionTools.callEmbeddingModel(prompt)];
|
|
1148
|
-
case 9: return [2 /*return*/, _e.sent()];
|
|
1149
|
-
case 10: throw new UnexpectedError("Unknown model variant \"".concat(prompt.modelRequirements.modelVariant, "\""));
|
|
1150
|
-
case 11: return [3 /*break*/, 13];
|
|
1151
|
-
case 12:
|
|
1152
|
-
error_1 = _e.sent();
|
|
1153
|
-
if (!(error_1 instanceof Error) || error_1 instanceof UnexpectedError) {
|
|
1154
|
-
throw error_1;
|
|
1155
|
-
}
|
|
1156
|
-
errors.push(error_1);
|
|
1157
|
-
return [3 /*break*/, 13];
|
|
1158
|
-
case 13:
|
|
1159
|
-
_b = _a.next();
|
|
1160
|
-
return [3 /*break*/, 2];
|
|
1161
|
-
case 14: return [3 /*break*/, 17];
|
|
1162
|
-
case 15:
|
|
1163
|
-
e_3_1 = _e.sent();
|
|
1164
|
-
e_3 = { error: e_3_1 };
|
|
1165
|
-
return [3 /*break*/, 17];
|
|
1166
|
-
case 16:
|
|
1167
|
-
try {
|
|
1168
|
-
if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
|
|
1169
|
-
}
|
|
1170
|
-
finally { if (e_3) throw e_3.error; }
|
|
1171
|
-
return [7 /*endfinally*/];
|
|
1172
|
-
case 17:
|
|
1173
|
-
if (errors.length === 1) {
|
|
1174
|
-
throw errors[0];
|
|
1175
|
-
}
|
|
1176
|
-
else if (errors.length > 1) {
|
|
1177
|
-
throw new PipelineExecutionError(
|
|
1178
|
-
// TODO: Tell which execution tools failed like
|
|
1179
|
-
// 1) OpenAI throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
1180
|
-
// 2) AnthropicClaude throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
1181
|
-
// 3) ...
|
|
1182
|
-
spaceTrim(function (block) { return "\n All execution tools failed:\n\n ".concat(block(errors
|
|
1183
|
-
.map(function (error, i) { return "".concat(i + 1, ") **").concat(error.name || 'Error', ":** ").concat(error.message); })
|
|
1184
|
-
.join('\n')), "\n\n "); }));
|
|
1185
|
-
}
|
|
1186
|
-
else if (this.llmExecutionTools.length === 0) {
|
|
1187
|
-
throw new PipelineExecutionError("You have not provided any `LlmExecutionTools`");
|
|
1188
|
-
}
|
|
1189
|
-
else {
|
|
1190
|
-
throw new PipelineExecutionError(spaceTrim(function (block) { return "\n You have not provided any `LlmExecutionTools` that support model variant \"".concat(prompt.modelRequirements.modelVariant, "\"\n\n Available `LlmExecutionTools`:\n ").concat(block(_this.description), "\n\n "); }));
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
});
|
|
868
|
+
function exportJson(options) {
|
|
869
|
+
var name = options.name, value = options.value, order = options.order, message = options.message;
|
|
870
|
+
checkSerializableAsJson({ name: name, value: value, message: message });
|
|
871
|
+
var orderedValue =
|
|
872
|
+
// TODO: Fix error "Type instantiation is excessively deep and possibly infinite."
|
|
873
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
874
|
+
// @ts-ignore
|
|
875
|
+
order === undefined
|
|
876
|
+
? deepClone(value)
|
|
877
|
+
: orderJson({
|
|
878
|
+
value: value,
|
|
879
|
+
// <- Note: checkSerializableAsJson asserts that the value is serializable as JSON
|
|
880
|
+
order: order,
|
|
1194
881
|
});
|
|
1195
|
-
|
|
1196
|
-
return
|
|
1197
|
-
}
|
|
882
|
+
$deepFreeze(orderedValue);
|
|
883
|
+
return orderedValue;
|
|
884
|
+
}
|
|
1198
885
|
/**
|
|
1199
|
-
* TODO: [🧠]
|
|
1200
|
-
* TODO: [🏖] If no llmTools have for example not defined `callCompletionModel` this will still return object with defined `callCompletionModel` which just throws `PipelineExecutionError`, make it undefined instead
|
|
1201
|
-
* Look how `countTotalUsage` (and `cacheLlmTools`) implements it
|
|
886
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
1202
887
|
*/
|
|
1203
888
|
|
|
1204
889
|
/**
|
|
1205
|
-
*
|
|
1206
|
-
*
|
|
1207
|
-
* @returns {LlmExecutionTools} Single wrapper for multiple LlmExecutionTools
|
|
1208
|
-
*
|
|
1209
|
-
* 0) If there is no LlmExecutionTools, it warns and returns valid but empty LlmExecutionTools
|
|
1210
|
-
* 1) If there is only one LlmExecutionTools, it returns it wrapped in a proxy object
|
|
1211
|
-
* 2) If there are multiple LlmExecutionTools, first will be used first, second will be used if the first hasn`t defined model variant or fails, etc.
|
|
1212
|
-
* 3) When all LlmExecutionTools fail, it throws an error with a list of all errors merged into one
|
|
1213
|
-
*
|
|
1214
|
-
*
|
|
1215
|
-
* Tip: You don't have to use this function directly, just pass an array of LlmExecutionTools to the `ExecutionTools`
|
|
890
|
+
* Order of keys in the pipeline JSON
|
|
1216
891
|
*
|
|
1217
892
|
* @public exported from `@promptbook/core`
|
|
1218
893
|
*/
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
894
|
+
var ORDER_OF_PIPELINE_JSON = [
|
|
895
|
+
// Note: [🍙] In this order will be pipeline serialized
|
|
896
|
+
'title',
|
|
897
|
+
'pipelineUrl',
|
|
898
|
+
'bookVersion',
|
|
899
|
+
'description',
|
|
900
|
+
'formfactorName',
|
|
901
|
+
'parameters',
|
|
902
|
+
'tasks',
|
|
903
|
+
'personas',
|
|
904
|
+
'preparations',
|
|
905
|
+
'knowledgeSources',
|
|
906
|
+
'knowledgePieces',
|
|
907
|
+
'sources', // <- TODO: [🧠] Where should the `sources` be
|
|
908
|
+
];
|
|
909
|
+
/**
|
|
910
|
+
* Nonce which is used for replacing things in strings
|
|
911
|
+
*
|
|
912
|
+
* @private within the repository
|
|
913
|
+
*/
|
|
914
|
+
var REPLACING_NONCE = 'u$k42k%!V2zo34w7Fu#@QUHYPW';
|
|
915
|
+
/**
|
|
916
|
+
* @@@
|
|
917
|
+
*
|
|
918
|
+
* @private within the repository
|
|
919
|
+
*/
|
|
920
|
+
var RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
|
|
921
|
+
/**
|
|
922
|
+
* @@@
|
|
923
|
+
*
|
|
924
|
+
* @private within the repository
|
|
925
|
+
*/
|
|
926
|
+
var RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;
|
|
927
|
+
/**
|
|
928
|
+
* The names of the parameters that are reserved for special purposes
|
|
929
|
+
*
|
|
930
|
+
* @public exported from `@promptbook/core`
|
|
931
|
+
*/
|
|
932
|
+
var RESERVED_PARAMETER_NAMES = exportJson({
|
|
933
|
+
name: 'RESERVED_PARAMETER_NAMES',
|
|
934
|
+
message: "The names of the parameters that are reserved for special purposes",
|
|
935
|
+
value: [
|
|
936
|
+
'content',
|
|
937
|
+
'context',
|
|
938
|
+
'knowledge',
|
|
939
|
+
'examples',
|
|
940
|
+
'modelName',
|
|
941
|
+
'currentDate',
|
|
942
|
+
// <- TODO: list here all command names
|
|
943
|
+
// <- TODO: Add more like 'date', 'modelName',...
|
|
944
|
+
// <- TODO: Add [emoji] + instructions ACRY when adding new reserved parameter
|
|
945
|
+
],
|
|
946
|
+
});
|
|
947
|
+
/**
|
|
948
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
949
|
+
*/
|
|
1237
950
|
|
|
1238
|
-
|
|
951
|
+
/**
|
|
952
|
+
* This error indicates that the promptbook object has valid syntax (=can be parsed) but contains logical errors (like circular dependencies)
|
|
953
|
+
*
|
|
954
|
+
* @public exported from `@promptbook/core`
|
|
955
|
+
*/
|
|
956
|
+
var PipelineLogicError = /** @class */ (function (_super) {
|
|
957
|
+
__extends(PipelineLogicError, _super);
|
|
958
|
+
function PipelineLogicError(message) {
|
|
959
|
+
var _this = _super.call(this, message) || this;
|
|
960
|
+
_this.name = 'PipelineLogicError';
|
|
961
|
+
Object.setPrototypeOf(_this, PipelineLogicError.prototype);
|
|
962
|
+
return _this;
|
|
963
|
+
}
|
|
964
|
+
return PipelineLogicError;
|
|
965
|
+
}(Error));
|
|
1239
966
|
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
967
|
+
/**
|
|
968
|
+
* Tests if given string is valid semantic version
|
|
969
|
+
*
|
|
970
|
+
* Note: There are two simmilar functions:
|
|
971
|
+
* - `isValidSemanticVersion` which tests any semantic version
|
|
972
|
+
* - `isValidPromptbookVersion` *(this one)* which tests just Promptbook versions
|
|
973
|
+
*
|
|
974
|
+
* @public exported from `@promptbook/utils`
|
|
975
|
+
*/
|
|
976
|
+
function isValidSemanticVersion(version) {
|
|
977
|
+
if (typeof version !== 'string') {
|
|
978
|
+
return false;
|
|
1248
979
|
}
|
|
1249
|
-
|
|
980
|
+
if (version.startsWith('0.0.0')) {
|
|
981
|
+
return false;
|
|
982
|
+
}
|
|
983
|
+
return /^\d+\.\d+\.\d+(-\d+)?$/i.test(version);
|
|
1250
984
|
}
|
|
985
|
+
|
|
1251
986
|
/**
|
|
1252
|
-
*
|
|
987
|
+
* Tests if given string is valid promptbook version
|
|
988
|
+
* It looks into list of known promptbook versions.
|
|
989
|
+
*
|
|
990
|
+
* @see https://www.npmjs.com/package/promptbook?activeTab=versions
|
|
991
|
+
* Note: When you are using for example promptbook 2.0.0 and there already is promptbook 3.0.0 it don`t know about it.
|
|
992
|
+
* Note: There are two simmilar functions:
|
|
993
|
+
* - `isValidSemanticVersion` which tests any semantic version
|
|
994
|
+
* - `isValidPromptbookVersion` *(this one)* which tests just Promptbook versions
|
|
995
|
+
*
|
|
996
|
+
* @public exported from `@promptbook/utils`
|
|
1253
997
|
*/
|
|
1254
|
-
|
|
1255
|
-
var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book.md",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.md`\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.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.book.md",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.md`\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.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.book.md",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- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-title.book.md`\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- Title should be concise and clear\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.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.book.md",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 Keywords\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-persona.book.md`\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.md"}];
|
|
998
|
+
function isValidPromptbookVersion(version) {
|
|
999
|
+
if (!isValidSemanticVersion(version)) {
|
|
1000
|
+
return false;
|
|
1001
|
+
}
|
|
1002
|
+
if ( /* version === '1.0.0' || */version === '2.0.0' || version === '3.0.0') {
|
|
1003
|
+
return false;
|
|
1004
|
+
}
|
|
1005
|
+
// <- TODO: [main] !!3 Check isValidPromptbookVersion against PROMPTBOOK_ENGINE_VERSIONS
|
|
1006
|
+
return true;
|
|
1007
|
+
}
|
|
1256
1008
|
|
|
1257
1009
|
/**
|
|
1258
|
-
*
|
|
1010
|
+
* Checks if an URL is reserved for private networks or localhost.
|
|
1259
1011
|
*
|
|
1260
|
-
*
|
|
1261
|
-
*
|
|
1262
|
-
*
|
|
1012
|
+
* Note: There are two simmilar functions:
|
|
1013
|
+
* - `isUrlOnPrivateNetwork` which tests full URL
|
|
1014
|
+
* - `isHostnameOnPrivateNetwork` *(this one)* which tests just hostname
|
|
1015
|
+
*
|
|
1016
|
+
* @public exported from `@promptbook/utils`
|
|
1263
1017
|
*/
|
|
1264
|
-
function
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
trailingComma: 'all',
|
|
1274
|
-
arrowParens: 'always',
|
|
1275
|
-
printWidth: 120,
|
|
1276
|
-
htmlWhitespaceSensitivity: 'ignore',
|
|
1277
|
-
jsxBracketSameLine: false,
|
|
1278
|
-
bracketSpacing: true,
|
|
1279
|
-
});
|
|
1018
|
+
function isHostnameOnPrivateNetwork(hostname) {
|
|
1019
|
+
if (hostname === 'example.com' ||
|
|
1020
|
+
hostname === 'localhost' ||
|
|
1021
|
+
hostname.endsWith('.localhost') ||
|
|
1022
|
+
hostname.endsWith('.local') ||
|
|
1023
|
+
hostname.endsWith('.test') ||
|
|
1024
|
+
hostname === '127.0.0.1' ||
|
|
1025
|
+
hostname === '::1') {
|
|
1026
|
+
return true;
|
|
1280
1027
|
}
|
|
1281
|
-
|
|
1282
|
-
//
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1028
|
+
if (hostname.includes(':')) {
|
|
1029
|
+
// IPv6
|
|
1030
|
+
var ipParts = hostname.split(':');
|
|
1031
|
+
return ipParts[0] === 'fc00' || ipParts[0] === 'fd00' || ipParts[0] === 'fe80';
|
|
1032
|
+
}
|
|
1033
|
+
else {
|
|
1034
|
+
// IPv4
|
|
1035
|
+
var ipParts = hostname.split('.').map(function (part) { return Number.parseInt(part, 10); });
|
|
1036
|
+
return (ipParts[0] === 10 ||
|
|
1037
|
+
(ipParts[0] === 172 && ipParts[1] >= 16 && ipParts[1] <= 31) ||
|
|
1038
|
+
(ipParts[0] === 192 && ipParts[1] === 168));
|
|
1288
1039
|
}
|
|
1289
1040
|
}
|
|
1290
1041
|
|
|
1291
1042
|
/**
|
|
1292
|
-
*
|
|
1043
|
+
* Checks if an IP address or hostname is reserved for private networks or localhost.
|
|
1044
|
+
*
|
|
1045
|
+
* Note: There are two simmilar functions:
|
|
1046
|
+
* - `isUrlOnPrivateNetwork` *(this one)* which tests full URL
|
|
1047
|
+
* - `isHostnameOnPrivateNetwork` which tests just hostname
|
|
1293
1048
|
*
|
|
1049
|
+
* @param {string} ipAddress - The IP address to check.
|
|
1050
|
+
* @returns {boolean} Returns true if the IP address is reserved for private networks or localhost, otherwise false.
|
|
1294
1051
|
* @public exported from `@promptbook/utils`
|
|
1295
1052
|
*/
|
|
1296
|
-
function
|
|
1297
|
-
|
|
1053
|
+
function isUrlOnPrivateNetwork(url) {
|
|
1054
|
+
if (typeof url === 'string') {
|
|
1055
|
+
url = new URL(url);
|
|
1056
|
+
}
|
|
1057
|
+
return isHostnameOnPrivateNetwork(url.hostname);
|
|
1298
1058
|
}
|
|
1299
1059
|
|
|
1300
1060
|
/**
|
|
1301
|
-
*
|
|
1061
|
+
* Tests if given string is valid URL.
|
|
1302
1062
|
*
|
|
1303
|
-
*
|
|
1304
|
-
*
|
|
1305
|
-
*
|
|
1306
|
-
*
|
|
1063
|
+
* Note: Dataurl are considered perfectly valid.
|
|
1064
|
+
* Note: There are two simmilar functions:
|
|
1065
|
+
* - `isValidUrl` which tests any URL
|
|
1066
|
+
* - `isValidPipelineUrl` *(this one)* which tests just promptbook URL
|
|
1067
|
+
*
|
|
1068
|
+
* @public exported from `@promptbook/utils`
|
|
1307
1069
|
*/
|
|
1308
|
-
function
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
var pipelineString = "# ".concat(title);
|
|
1312
|
-
if (description) {
|
|
1313
|
-
pipelineString += '\n\n';
|
|
1314
|
-
pipelineString += description;
|
|
1315
|
-
}
|
|
1316
|
-
var commands = [];
|
|
1317
|
-
if (pipelineUrl) {
|
|
1318
|
-
commands.push("PIPELINE URL ".concat(pipelineUrl));
|
|
1319
|
-
}
|
|
1320
|
-
if (bookVersion !== "undefined") {
|
|
1321
|
-
commands.push("BOOK VERSION ".concat(bookVersion));
|
|
1070
|
+
function isValidUrl(url) {
|
|
1071
|
+
if (typeof url !== 'string') {
|
|
1072
|
+
return false;
|
|
1322
1073
|
}
|
|
1323
|
-
// TODO: [main] !!!!! This increases size of the bundle and is probbably not necessary
|
|
1324
|
-
pipelineString = prettifyMarkdown(pipelineString);
|
|
1325
1074
|
try {
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
return isInput;
|
|
1329
|
-
})), _h = _g.next(); !_h.done; _h = _g.next()) {
|
|
1330
|
-
var parameter = _h.value;
|
|
1331
|
-
commands.push("INPUT PARAMETER ".concat(taskParameterJsonToString(parameter)));
|
|
1075
|
+
if (url.startsWith('blob:')) {
|
|
1076
|
+
url = url.replace(/^blob:/, '');
|
|
1332
1077
|
}
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
try {
|
|
1337
|
-
if (_h && !_h.done && (_a = _g.return)) _a.call(_g);
|
|
1078
|
+
var urlObject = new URL(url /* because fail is handled */);
|
|
1079
|
+
if (!['http:', 'https:', 'data:'].includes(urlObject.protocol)) {
|
|
1080
|
+
return false;
|
|
1338
1081
|
}
|
|
1339
|
-
|
|
1082
|
+
return true;
|
|
1340
1083
|
}
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
var isOutput = _a.isOutput;
|
|
1344
|
-
return isOutput;
|
|
1345
|
-
})), _k = _j.next(); !_k.done; _k = _j.next()) {
|
|
1346
|
-
var parameter = _k.value;
|
|
1347
|
-
commands.push("OUTPUT PARAMETER ".concat(taskParameterJsonToString(parameter)));
|
|
1348
|
-
}
|
|
1084
|
+
catch (error) {
|
|
1085
|
+
return false;
|
|
1349
1086
|
}
|
|
1350
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
1351
|
-
finally {
|
|
1352
|
-
try {
|
|
1353
|
-
if (_k && !_k.done && (_b = _j.return)) _b.call(_j);
|
|
1354
|
-
}
|
|
1355
|
-
finally { if (e_2) throw e_2.error; }
|
|
1356
|
-
}
|
|
1357
|
-
pipelineString += '\n\n';
|
|
1358
|
-
pipelineString += commands.map(function (command) { return "- ".concat(command); }).join('\n');
|
|
1359
|
-
try {
|
|
1360
|
-
for (var tasks_1 = __values(tasks), tasks_1_1 = tasks_1.next(); !tasks_1_1.done; tasks_1_1 = tasks_1.next()) {
|
|
1361
|
-
var task = tasks_1_1.value;
|
|
1362
|
-
var
|
|
1363
|
-
/* Note: Not using:> name, */
|
|
1364
|
-
title_1 = task.title, description_1 = task.description,
|
|
1365
|
-
/* Note: dependentParameterNames, */
|
|
1366
|
-
jokers = task.jokerParameterNames, taskType = task.taskType, content = task.content, postprocessing = task.postprocessingFunctionNames, expectations = task.expectations, format = task.format, resultingParameterName = task.resultingParameterName;
|
|
1367
|
-
pipelineString += '\n\n';
|
|
1368
|
-
pipelineString += "## ".concat(title_1);
|
|
1369
|
-
if (description_1) {
|
|
1370
|
-
pipelineString += '\n\n';
|
|
1371
|
-
pipelineString += description_1;
|
|
1372
|
-
}
|
|
1373
|
-
var commands_1 = [];
|
|
1374
|
-
var contentLanguage = 'text';
|
|
1375
|
-
if (taskType === 'PROMPT_TASK') {
|
|
1376
|
-
var modelRequirements = task.modelRequirements;
|
|
1377
|
-
var _l = modelRequirements || {}, modelName = _l.modelName, modelVariant = _l.modelVariant;
|
|
1378
|
-
// Note: Do nothing, it is default
|
|
1379
|
-
// commands.push(`PROMPT`);
|
|
1380
|
-
if (modelVariant) {
|
|
1381
|
-
commands_1.push("MODEL VARIANT ".concat(capitalize(modelVariant)));
|
|
1382
|
-
}
|
|
1383
|
-
if (modelName) {
|
|
1384
|
-
commands_1.push("MODEL NAME `".concat(modelName, "`"));
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
|
-
else if (taskType === 'SIMPLE_TASK') {
|
|
1388
|
-
commands_1.push("SIMPLE TEMPLATE");
|
|
1389
|
-
// Note: Nothing special here
|
|
1390
|
-
}
|
|
1391
|
-
else if (taskType === 'SCRIPT_TASK') {
|
|
1392
|
-
commands_1.push("SCRIPT");
|
|
1393
|
-
if (task.contentLanguage) {
|
|
1394
|
-
contentLanguage = task.contentLanguage;
|
|
1395
|
-
}
|
|
1396
|
-
else {
|
|
1397
|
-
contentLanguage = '';
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
else if (taskType === 'DIALOG_TASK') {
|
|
1401
|
-
commands_1.push("DIALOG");
|
|
1402
|
-
// Note: Nothing special here
|
|
1403
|
-
} // <- }else if([🅱]
|
|
1404
|
-
if (jokers) {
|
|
1405
|
-
try {
|
|
1406
|
-
for (var jokers_1 = (e_4 = void 0, __values(jokers)), jokers_1_1 = jokers_1.next(); !jokers_1_1.done; jokers_1_1 = jokers_1.next()) {
|
|
1407
|
-
var joker = jokers_1_1.value;
|
|
1408
|
-
commands_1.push("JOKER {".concat(joker, "}"));
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
1411
|
-
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
1412
|
-
finally {
|
|
1413
|
-
try {
|
|
1414
|
-
if (jokers_1_1 && !jokers_1_1.done && (_d = jokers_1.return)) _d.call(jokers_1);
|
|
1415
|
-
}
|
|
1416
|
-
finally { if (e_4) throw e_4.error; }
|
|
1417
|
-
}
|
|
1418
|
-
} /* not else */
|
|
1419
|
-
if (postprocessing) {
|
|
1420
|
-
try {
|
|
1421
|
-
for (var postprocessing_1 = (e_5 = void 0, __values(postprocessing)), postprocessing_1_1 = postprocessing_1.next(); !postprocessing_1_1.done; postprocessing_1_1 = postprocessing_1.next()) {
|
|
1422
|
-
var postprocessingFunctionName = postprocessing_1_1.value;
|
|
1423
|
-
commands_1.push("POSTPROCESSING `".concat(postprocessingFunctionName, "`"));
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1426
|
-
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
1427
|
-
finally {
|
|
1428
|
-
try {
|
|
1429
|
-
if (postprocessing_1_1 && !postprocessing_1_1.done && (_e = postprocessing_1.return)) _e.call(postprocessing_1);
|
|
1430
|
-
}
|
|
1431
|
-
finally { if (e_5) throw e_5.error; }
|
|
1432
|
-
}
|
|
1433
|
-
} /* not else */
|
|
1434
|
-
if (expectations) {
|
|
1435
|
-
try {
|
|
1436
|
-
for (var _m = (e_6 = void 0, __values(Object.entries(expectations))), _o = _m.next(); !_o.done; _o = _m.next()) {
|
|
1437
|
-
var _p = __read(_o.value, 2), unit = _p[0], _q = _p[1], min = _q.min, max = _q.max;
|
|
1438
|
-
if (min === max) {
|
|
1439
|
-
commands_1.push("EXPECT EXACTLY ".concat(min, " ").concat(capitalize(unit + (min > 1 ? 's' : ''))));
|
|
1440
|
-
}
|
|
1441
|
-
else {
|
|
1442
|
-
if (min !== undefined) {
|
|
1443
|
-
commands_1.push("EXPECT MIN ".concat(min, " ").concat(capitalize(unit + (min > 1 ? 's' : ''))));
|
|
1444
|
-
} /* not else */
|
|
1445
|
-
if (max !== undefined) {
|
|
1446
|
-
commands_1.push("EXPECT MAX ".concat(max, " ").concat(capitalize(unit + (max > 1 ? 's' : ''))));
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
1452
|
-
finally {
|
|
1453
|
-
try {
|
|
1454
|
-
if (_o && !_o.done && (_f = _m.return)) _f.call(_m);
|
|
1455
|
-
}
|
|
1456
|
-
finally { if (e_6) throw e_6.error; }
|
|
1457
|
-
}
|
|
1458
|
-
} /* not else */
|
|
1459
|
-
if (format) {
|
|
1460
|
-
if (format === 'JSON') {
|
|
1461
|
-
// TODO: @deprecated remove
|
|
1462
|
-
commands_1.push("FORMAT JSON");
|
|
1463
|
-
}
|
|
1464
|
-
} /* not else */
|
|
1465
|
-
pipelineString += '\n\n';
|
|
1466
|
-
pipelineString += commands_1.map(function (command) { return "- ".concat(command); }).join('\n');
|
|
1467
|
-
pipelineString += '\n\n';
|
|
1468
|
-
pipelineString += '```' + contentLanguage;
|
|
1469
|
-
pipelineString += '\n';
|
|
1470
|
-
pipelineString += spaceTrim(content);
|
|
1471
|
-
// <- TODO: [main] !!! Escape
|
|
1472
|
-
// <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
|
|
1473
|
-
pipelineString += '\n';
|
|
1474
|
-
pipelineString += '```';
|
|
1475
|
-
pipelineString += '\n\n';
|
|
1476
|
-
pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: [main] !!! If the parameter here has description, add it and use taskParameterJsonToString
|
|
1477
|
-
}
|
|
1478
|
-
}
|
|
1479
|
-
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
1480
|
-
finally {
|
|
1481
|
-
try {
|
|
1482
|
-
if (tasks_1_1 && !tasks_1_1.done && (_c = tasks_1.return)) _c.call(tasks_1);
|
|
1483
|
-
}
|
|
1484
|
-
finally { if (e_3) throw e_3.error; }
|
|
1485
|
-
}
|
|
1486
|
-
return pipelineString;
|
|
1487
|
-
}
|
|
1488
|
-
/**
|
|
1489
|
-
* @private internal utility of `pipelineJsonToString`
|
|
1490
|
-
*/
|
|
1491
|
-
function taskParameterJsonToString(taskParameterJson) {
|
|
1492
|
-
var name = taskParameterJson.name, description = taskParameterJson.description;
|
|
1493
|
-
var parameterString = "{".concat(name, "}");
|
|
1494
|
-
if (description) {
|
|
1495
|
-
parameterString = "".concat(parameterString, " ").concat(description);
|
|
1496
|
-
}
|
|
1497
|
-
return parameterString;
|
|
1498
1087
|
}
|
|
1499
|
-
/**
|
|
1500
|
-
* TODO: [🛋] Implement new features and commands into `pipelineJsonToString` + `taskParameterJsonToString` , use `stringifyCommand`
|
|
1501
|
-
* TODO: [🧠] Is there a way to auto-detect missing features in pipelineJsonToString
|
|
1502
|
-
* TODO: [🏛] Maybe make some markdown builder
|
|
1503
|
-
* TODO: [🏛] Escape all
|
|
1504
|
-
* TODO: [🧠] Should be in generated .book.md file GENERATOR_WARNING
|
|
1505
|
-
*/
|
|
1506
|
-
|
|
1507
|
-
/**
|
|
1508
|
-
* This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
|
|
1509
|
-
*
|
|
1510
|
-
* @public exported from `@promptbook/core`
|
|
1511
|
-
*/
|
|
1512
|
-
var ParseError = /** @class */ (function (_super) {
|
|
1513
|
-
__extends(ParseError, _super);
|
|
1514
|
-
function ParseError(message) {
|
|
1515
|
-
var _this = _super.call(this, message) || this;
|
|
1516
|
-
_this.name = 'ParseError';
|
|
1517
|
-
Object.setPrototypeOf(_this, ParseError.prototype);
|
|
1518
|
-
return _this;
|
|
1519
|
-
}
|
|
1520
|
-
return ParseError;
|
|
1521
|
-
}(Error));
|
|
1522
|
-
/**
|
|
1523
|
-
* TODO: Maybe split `ParseError` and `ApplyError`
|
|
1524
|
-
*/
|
|
1525
|
-
|
|
1526
|
-
/**
|
|
1527
|
-
* This error indicates that the promptbook object has valid syntax (=can be parsed) but contains logical errors (like circular dependencies)
|
|
1528
|
-
*
|
|
1529
|
-
* @public exported from `@promptbook/core`
|
|
1530
|
-
*/
|
|
1531
|
-
var PipelineLogicError = /** @class */ (function (_super) {
|
|
1532
|
-
__extends(PipelineLogicError, _super);
|
|
1533
|
-
function PipelineLogicError(message) {
|
|
1534
|
-
var _this = _super.call(this, message) || this;
|
|
1535
|
-
_this.name = 'PipelineLogicError';
|
|
1536
|
-
Object.setPrototypeOf(_this, PipelineLogicError.prototype);
|
|
1537
|
-
return _this;
|
|
1538
|
-
}
|
|
1539
|
-
return PipelineLogicError;
|
|
1540
|
-
}(Error));
|
|
1541
1088
|
|
|
1542
1089
|
/**
|
|
1543
|
-
* Tests if given string is valid
|
|
1090
|
+
* Tests if given string is valid pipeline URL URL.
|
|
1544
1091
|
*
|
|
1545
1092
|
* Note: There are two simmilar functions:
|
|
1546
|
-
* - `
|
|
1547
|
-
* - `
|
|
1093
|
+
* - `isValidUrl` which tests any URL
|
|
1094
|
+
* - `isValidPipelineUrl` *(this one)* which tests just pipeline URL
|
|
1548
1095
|
*
|
|
1549
1096
|
* @public exported from `@promptbook/utils`
|
|
1550
1097
|
*/
|
|
1551
|
-
function
|
|
1552
|
-
if (
|
|
1098
|
+
function isValidPipelineUrl(url) {
|
|
1099
|
+
if (!isValidUrl(url)) {
|
|
1553
1100
|
return false;
|
|
1554
1101
|
}
|
|
1555
|
-
if (
|
|
1102
|
+
if (!url.startsWith('https://')) {
|
|
1556
1103
|
return false;
|
|
1557
1104
|
}
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
/**
|
|
1562
|
-
* Tests if given string is valid promptbook version
|
|
1563
|
-
* It looks into list of known promptbook versions.
|
|
1564
|
-
*
|
|
1565
|
-
* @see https://www.npmjs.com/package/promptbook?activeTab=versions
|
|
1566
|
-
* Note: When you are using for example promptbook 2.0.0 and there already is promptbook 3.0.0 it don`t know about it.
|
|
1567
|
-
* Note: There are two simmilar functions:
|
|
1568
|
-
* - `isValidSemanticVersion` which tests any semantic version
|
|
1569
|
-
* - `isValidPromptbookVersion` *(this one)* which tests just Promptbook versions
|
|
1570
|
-
*
|
|
1571
|
-
* @public exported from `@promptbook/utils`
|
|
1572
|
-
*/
|
|
1573
|
-
function isValidPromptbookVersion(version) {
|
|
1574
|
-
if (!isValidSemanticVersion(version)) {
|
|
1105
|
+
if (url.includes('#')) {
|
|
1106
|
+
// TODO: [🐠]
|
|
1575
1107
|
return false;
|
|
1576
1108
|
}
|
|
1577
|
-
if (
|
|
1109
|
+
if (isUrlOnPrivateNetwork(url)) {
|
|
1578
1110
|
return false;
|
|
1579
1111
|
}
|
|
1580
|
-
// <- TODO: [main] !!! Check isValidPromptbookVersion against PROMPTBOOK_ENGINE_VERSIONS
|
|
1581
1112
|
return true;
|
|
1582
1113
|
}
|
|
1114
|
+
/**
|
|
1115
|
+
* TODO: [🐠] Maybe more info why the URL is invalid
|
|
1116
|
+
*/
|
|
1583
1117
|
|
|
1584
1118
|
/**
|
|
1585
|
-
*
|
|
1119
|
+
* Validates PipelineJson if it is logically valid
|
|
1586
1120
|
*
|
|
1587
|
-
*
|
|
1588
|
-
* -
|
|
1589
|
-
* - `isHostnameOnPrivateNetwork` *(this one)* which tests just hostname
|
|
1121
|
+
* It checks:
|
|
1122
|
+
* - if it has correct parameters dependency
|
|
1590
1123
|
*
|
|
1591
|
-
*
|
|
1124
|
+
* It does NOT check:
|
|
1125
|
+
* - if it is valid json
|
|
1126
|
+
* - if it is meaningful
|
|
1127
|
+
*
|
|
1128
|
+
* @param pipeline valid or invalid PipelineJson
|
|
1129
|
+
* @returns the same pipeline if it is logically valid
|
|
1130
|
+
* @throws {PipelineLogicError} on logical error in the pipeline
|
|
1131
|
+
* @public exported from `@promptbook/core`
|
|
1592
1132
|
*/
|
|
1593
|
-
function
|
|
1594
|
-
if (
|
|
1595
|
-
|
|
1596
|
-
hostname.endsWith('.localhost') ||
|
|
1597
|
-
hostname.endsWith('.local') ||
|
|
1598
|
-
hostname.endsWith('.test') ||
|
|
1599
|
-
hostname === '127.0.0.1' ||
|
|
1600
|
-
hostname === '::1') {
|
|
1601
|
-
return true;
|
|
1602
|
-
}
|
|
1603
|
-
if (hostname.includes(':')) {
|
|
1604
|
-
// IPv6
|
|
1605
|
-
var ipParts = hostname.split(':');
|
|
1606
|
-
return ipParts[0] === 'fc00' || ipParts[0] === 'fd00' || ipParts[0] === 'fe80';
|
|
1607
|
-
}
|
|
1608
|
-
else {
|
|
1609
|
-
// IPv4
|
|
1610
|
-
var ipParts = hostname.split('.').map(function (part) { return Number.parseInt(part, 10); });
|
|
1611
|
-
return (ipParts[0] === 10 ||
|
|
1612
|
-
(ipParts[0] === 172 && ipParts[1] >= 16 && ipParts[1] <= 31) ||
|
|
1613
|
-
(ipParts[0] === 192 && ipParts[1] === 168));
|
|
1614
|
-
}
|
|
1615
|
-
}
|
|
1616
|
-
|
|
1617
|
-
/**
|
|
1618
|
-
* Checks if an IP address or hostname is reserved for private networks or localhost.
|
|
1619
|
-
*
|
|
1620
|
-
* Note: There are two simmilar functions:
|
|
1621
|
-
* - `isUrlOnPrivateNetwork` *(this one)* which tests full URL
|
|
1622
|
-
* - `isHostnameOnPrivateNetwork` which tests just hostname
|
|
1623
|
-
*
|
|
1624
|
-
* @param {string} ipAddress - The IP address to check.
|
|
1625
|
-
* @returns {boolean} Returns true if the IP address is reserved for private networks or localhost, otherwise false.
|
|
1626
|
-
* @public exported from `@promptbook/utils`
|
|
1627
|
-
*/
|
|
1628
|
-
function isUrlOnPrivateNetwork(url) {
|
|
1629
|
-
if (typeof url === 'string') {
|
|
1630
|
-
url = new URL(url);
|
|
1631
|
-
}
|
|
1632
|
-
return isHostnameOnPrivateNetwork(url.hostname);
|
|
1633
|
-
}
|
|
1634
|
-
|
|
1635
|
-
/**
|
|
1636
|
-
* Tests if given string is valid URL.
|
|
1637
|
-
*
|
|
1638
|
-
* Note: Dataurl are considered perfectly valid.
|
|
1639
|
-
* Note: There are two simmilar functions:
|
|
1640
|
-
* - `isValidUrl` which tests any URL
|
|
1641
|
-
* - `isValidPipelineUrl` *(this one)* which tests just promptbook URL
|
|
1642
|
-
*
|
|
1643
|
-
* @public exported from `@promptbook/utils`
|
|
1644
|
-
*/
|
|
1645
|
-
function isValidUrl(url) {
|
|
1646
|
-
if (typeof url !== 'string') {
|
|
1647
|
-
return false;
|
|
1648
|
-
}
|
|
1649
|
-
try {
|
|
1650
|
-
if (url.startsWith('blob:')) {
|
|
1651
|
-
url = url.replace(/^blob:/, '');
|
|
1652
|
-
}
|
|
1653
|
-
var urlObject = new URL(url /* because fail is handled */);
|
|
1654
|
-
if (!['http:', 'https:', 'data:'].includes(urlObject.protocol)) {
|
|
1655
|
-
return false;
|
|
1656
|
-
}
|
|
1657
|
-
return true;
|
|
1658
|
-
}
|
|
1659
|
-
catch (error) {
|
|
1660
|
-
return false;
|
|
1661
|
-
}
|
|
1662
|
-
}
|
|
1663
|
-
|
|
1664
|
-
/**
|
|
1665
|
-
* Tests if given string is valid pipeline URL URL.
|
|
1666
|
-
*
|
|
1667
|
-
* Note: There are two simmilar functions:
|
|
1668
|
-
* - `isValidUrl` which tests any URL
|
|
1669
|
-
* - `isValidPipelineUrl` *(this one)* which tests just pipeline URL
|
|
1670
|
-
*
|
|
1671
|
-
* @public exported from `@promptbook/utils`
|
|
1672
|
-
*/
|
|
1673
|
-
function isValidPipelineUrl(url) {
|
|
1674
|
-
if (!isValidUrl(url)) {
|
|
1675
|
-
return false;
|
|
1676
|
-
}
|
|
1677
|
-
if (!url.startsWith('https://')) {
|
|
1678
|
-
return false;
|
|
1679
|
-
}
|
|
1680
|
-
if (!(url.endsWith('.book.md') || url.endsWith('.book') || url.endsWith('.book.md') || url.endsWith('.ptbk'))) {
|
|
1681
|
-
return false;
|
|
1682
|
-
}
|
|
1683
|
-
if (url.includes('#')) {
|
|
1684
|
-
// TODO: [🐠]
|
|
1685
|
-
return false;
|
|
1686
|
-
}
|
|
1687
|
-
if (isUrlOnPrivateNetwork(url)) {
|
|
1688
|
-
return false;
|
|
1689
|
-
}
|
|
1690
|
-
return true;
|
|
1691
|
-
}
|
|
1692
|
-
/**
|
|
1693
|
-
* TODO: [🐠] Maybe more info why the URL is invalid
|
|
1694
|
-
*/
|
|
1695
|
-
|
|
1696
|
-
/**
|
|
1697
|
-
* Validates PipelineJson if it is logically valid
|
|
1698
|
-
*
|
|
1699
|
-
* It checks:
|
|
1700
|
-
* - if it has correct parameters dependency
|
|
1701
|
-
*
|
|
1702
|
-
* It does NOT check:
|
|
1703
|
-
* - if it is valid json
|
|
1704
|
-
* - if it is meaningful
|
|
1705
|
-
*
|
|
1706
|
-
* @param pipeline valid or invalid PipelineJson
|
|
1707
|
-
* @returns the same pipeline if it is logically valid
|
|
1708
|
-
* @throws {PipelineLogicError} on logical error in the pipeline
|
|
1709
|
-
* @public exported from `@promptbook/core`
|
|
1710
|
-
*/
|
|
1711
|
-
function validatePipeline(pipeline) {
|
|
1712
|
-
if (IS_PIPELINE_LOGIC_VALIDATED) {
|
|
1713
|
-
validatePipelineCore(pipeline);
|
|
1133
|
+
function validatePipeline(pipeline) {
|
|
1134
|
+
if (IS_PIPELINE_LOGIC_VALIDATED) {
|
|
1135
|
+
validatePipeline_InnerFunction(pipeline);
|
|
1714
1136
|
}
|
|
1715
1137
|
else {
|
|
1716
1138
|
try {
|
|
1717
|
-
|
|
1139
|
+
validatePipeline_InnerFunction(pipeline);
|
|
1718
1140
|
}
|
|
1719
1141
|
catch (error) {
|
|
1720
1142
|
if (!(error instanceof PipelineLogicError)) {
|
|
@@ -1728,7 +1150,7 @@ function validatePipeline(pipeline) {
|
|
|
1728
1150
|
/**
|
|
1729
1151
|
* @private internal function for `validatePipeline`
|
|
1730
1152
|
*/
|
|
1731
|
-
function
|
|
1153
|
+
function validatePipeline_InnerFunction(pipeline) {
|
|
1732
1154
|
// TODO: [🧠] Maybe test if promptbook is a promise and make specific error case for that
|
|
1733
1155
|
var e_1, _a, e_2, _b, e_3, _c;
|
|
1734
1156
|
var pipelineIdentification = (function () {
|
|
@@ -1952,11 +1374,11 @@ function validatePipelineCore(pipeline) {
|
|
|
1952
1374
|
_loop_3();
|
|
1953
1375
|
}
|
|
1954
1376
|
// Note: Check that formfactor is corresponding to the pipeline interface
|
|
1955
|
-
// TODO:
|
|
1377
|
+
// TODO: !!6 Implement this
|
|
1956
1378
|
// pipeline.formfactorName
|
|
1957
1379
|
}
|
|
1958
1380
|
/**
|
|
1959
|
-
* TODO:
|
|
1381
|
+
* TODO: [🧞♀️] Do not allow joker + foreach
|
|
1960
1382
|
* TODO: [🧠] Work with promptbookVersion
|
|
1961
1383
|
* TODO: Use here some json-schema, Zod or something similar and change it to:
|
|
1962
1384
|
* > /**
|
|
@@ -1968,11 +1390,11 @@ function validatePipelineCore(pipeline) {
|
|
|
1968
1390
|
* > ex port function validatePipeline(promptbook: really_unknown): asserts promptbook is PipelineJson {
|
|
1969
1391
|
*/
|
|
1970
1392
|
/**
|
|
1971
|
-
* TODO: [🧳][main]
|
|
1972
|
-
* TODO: [🧳][🐝][main]
|
|
1973
|
-
* TODO: [🧳][main]
|
|
1974
|
-
* TODO: [🧳][main]
|
|
1975
|
-
* TODO: [🧳][main]
|
|
1393
|
+
* TODO: [🧳][main] !!4 Validate that all examples match expectations
|
|
1394
|
+
* TODO: [🧳][🐝][main] !!4 Validate that knowledge is valid (non-void)
|
|
1395
|
+
* TODO: [🧳][main] !!4 Validate that persona can be used only with CHAT variant
|
|
1396
|
+
* TODO: [🧳][main] !!4 Validate that parameter with reserved name not used RESERVED_PARAMETER_NAMES
|
|
1397
|
+
* TODO: [🧳][main] !!4 Validate that reserved parameter is not used as joker
|
|
1976
1398
|
* TODO: [🧠] Validation not only logic itself but imports around - files and websites and rerefenced pipelines exists
|
|
1977
1399
|
* TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
|
|
1978
1400
|
*/
|
|
@@ -2108,7 +1530,7 @@ var SimplePipelineCollection = /** @class */ (function () {
|
|
|
2108
1530
|
pipelineJsonToString(unpreparePipeline(pipeline)) !==
|
|
2109
1531
|
pipelineJsonToString(unpreparePipeline(this.collection.get(pipeline.pipelineUrl)))) {
|
|
2110
1532
|
var existing = this.collection.get(pipeline.pipelineUrl);
|
|
2111
|
-
throw new PipelineUrlError(spaceTrim$1("\n Pipeline with URL
|
|
1533
|
+
throw new PipelineUrlError(spaceTrim$1("\n Pipeline with URL ".concat(pipeline.pipelineUrl, " is already in the collection \uD83C\uDF4E\n\n Conflicting files:\n ").concat(existing.sourceFile || 'Unknown', "\n ").concat(pipeline.sourceFile || 'Unknown', "\n\n Note: You have probably forgotten to run \"ptbk make\" to update the collection\n Note: Pipelines with the same URL are not allowed\n Only exepction is when the pipelines are identical\n\n ")));
|
|
2112
1534
|
}
|
|
2113
1535
|
// Note: [🧠] Overwrite existing pipeline with the same URL
|
|
2114
1536
|
this.collection.set(pipeline.pipelineUrl, pipeline);
|
|
@@ -2173,6 +1595,38 @@ function createCollectionFromJson() {
|
|
|
2173
1595
|
return new (SimplePipelineCollection.bind.apply(SimplePipelineCollection, __spreadArray([void 0], __read(promptbooks), false)))();
|
|
2174
1596
|
}
|
|
2175
1597
|
|
|
1598
|
+
/**
|
|
1599
|
+
* This error type indicates that some tools are missing for pipeline execution or preparation
|
|
1600
|
+
*
|
|
1601
|
+
* @public exported from `@promptbook/core`
|
|
1602
|
+
*/
|
|
1603
|
+
var MissingToolsError = /** @class */ (function (_super) {
|
|
1604
|
+
__extends(MissingToolsError, _super);
|
|
1605
|
+
function MissingToolsError(message) {
|
|
1606
|
+
var _this = _super.call(this, spaceTrim$1(function (block) { return "\n ".concat(block(message), "\n\n Note: You have probbably forgot to provide some tools for pipeline execution or preparation\n\n "); })) || this;
|
|
1607
|
+
_this.name = 'MissingToolsError';
|
|
1608
|
+
Object.setPrototypeOf(_this, MissingToolsError.prototype);
|
|
1609
|
+
return _this;
|
|
1610
|
+
}
|
|
1611
|
+
return MissingToolsError;
|
|
1612
|
+
}(Error));
|
|
1613
|
+
|
|
1614
|
+
/**
|
|
1615
|
+
* This error indicates errors during the execution of the pipeline
|
|
1616
|
+
*
|
|
1617
|
+
* @public exported from `@promptbook/core`
|
|
1618
|
+
*/
|
|
1619
|
+
var PipelineExecutionError = /** @class */ (function (_super) {
|
|
1620
|
+
__extends(PipelineExecutionError, _super);
|
|
1621
|
+
function PipelineExecutionError(message) {
|
|
1622
|
+
var _this = _super.call(this, message) || this;
|
|
1623
|
+
_this.name = 'PipelineExecutionError';
|
|
1624
|
+
Object.setPrototypeOf(_this, PipelineExecutionError.prototype);
|
|
1625
|
+
return _this;
|
|
1626
|
+
}
|
|
1627
|
+
return PipelineExecutionError;
|
|
1628
|
+
}(Error));
|
|
1629
|
+
|
|
2176
1630
|
/**
|
|
2177
1631
|
* This error indicates problems parsing the format value
|
|
2178
1632
|
*
|
|
@@ -2412,11 +1866,16 @@ function assertsExecutionSuccessful(executionResult) {
|
|
|
2412
1866
|
/**
|
|
2413
1867
|
* Determine if the pipeline is fully prepared
|
|
2414
1868
|
*
|
|
1869
|
+
* @see https://github.com/webgptorg/promptbook/discussions/196
|
|
1870
|
+
*
|
|
2415
1871
|
* @public exported from `@promptbook/core`
|
|
2416
1872
|
*/
|
|
2417
1873
|
function isPipelinePrepared(pipeline) {
|
|
2418
1874
|
// Note: Ignoring `pipeline.preparations` @@@
|
|
2419
1875
|
// Note: Ignoring `pipeline.knowledgePieces` @@@
|
|
1876
|
+
if (pipeline.title === undefined || pipeline.title === '' || pipeline.title === DEFAULT_BOOK_TITLE) {
|
|
1877
|
+
return false;
|
|
1878
|
+
}
|
|
2420
1879
|
if (!pipeline.personas.every(function (persona) { return persona.modelRequirements !== undefined; })) {
|
|
2421
1880
|
return false;
|
|
2422
1881
|
}
|
|
@@ -2432,7 +1891,7 @@ function isPipelinePrepared(pipeline) {
|
|
|
2432
1891
|
return true;
|
|
2433
1892
|
}
|
|
2434
1893
|
/**
|
|
2435
|
-
* TODO: [🔃][main]
|
|
1894
|
+
* TODO: [🔃][main] If the pipeline was prepared with different version or different set of models, prepare it once again
|
|
2436
1895
|
* TODO: [🐠] Maybe base this on `makeValidator`
|
|
2437
1896
|
* TODO: [🧊] Pipeline can be partially prepared, this should return true ONLY if fully prepared
|
|
2438
1897
|
* TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
|
|
@@ -2441,6 +1900,81 @@ function isPipelinePrepared(pipeline) {
|
|
|
2441
1900
|
* - [♨] Are tasks prepared
|
|
2442
1901
|
*/
|
|
2443
1902
|
|
|
1903
|
+
/**
|
|
1904
|
+
* Format either small or big number
|
|
1905
|
+
*
|
|
1906
|
+
* @public exported from `@promptbook/utils`
|
|
1907
|
+
*/
|
|
1908
|
+
function numberToString(value) {
|
|
1909
|
+
if (value === 0) {
|
|
1910
|
+
return '0';
|
|
1911
|
+
}
|
|
1912
|
+
else if (Number.isNaN(value)) {
|
|
1913
|
+
return VALUE_STRINGS.nan;
|
|
1914
|
+
}
|
|
1915
|
+
else if (value === Infinity) {
|
|
1916
|
+
return VALUE_STRINGS.infinity;
|
|
1917
|
+
}
|
|
1918
|
+
else if (value === -Infinity) {
|
|
1919
|
+
return VALUE_STRINGS.negativeInfinity;
|
|
1920
|
+
}
|
|
1921
|
+
for (var exponent = 0; exponent < 15; exponent++) {
|
|
1922
|
+
var factor = Math.pow(10, exponent);
|
|
1923
|
+
var valueRounded = Math.round(value * factor) / factor;
|
|
1924
|
+
if (Math.abs(value - valueRounded) / value < SMALL_NUMBER) {
|
|
1925
|
+
return valueRounded.toFixed(exponent);
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
return value.toString();
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1931
|
+
/**
|
|
1932
|
+
* Function `valueToString` will convert the given value to string
|
|
1933
|
+
* This is useful and used in the `templateParameters` function
|
|
1934
|
+
*
|
|
1935
|
+
* Note: This function is not just calling `toString` method
|
|
1936
|
+
* It's more complex and can handle this conversion specifically for LLM models
|
|
1937
|
+
* See `VALUE_STRINGS`
|
|
1938
|
+
*
|
|
1939
|
+
* Note: There are 2 similar functions
|
|
1940
|
+
* - `valueToString` converts value to string for LLM models as human-readable string
|
|
1941
|
+
* - `asSerializable` converts value to string to preserve full information to be able to convert it back
|
|
1942
|
+
*
|
|
1943
|
+
* @public exported from `@promptbook/utils`
|
|
1944
|
+
*/
|
|
1945
|
+
function valueToString(value) {
|
|
1946
|
+
try {
|
|
1947
|
+
if (value === '') {
|
|
1948
|
+
return VALUE_STRINGS.empty;
|
|
1949
|
+
}
|
|
1950
|
+
else if (value === null) {
|
|
1951
|
+
return VALUE_STRINGS.null;
|
|
1952
|
+
}
|
|
1953
|
+
else if (value === undefined) {
|
|
1954
|
+
return VALUE_STRINGS.undefined;
|
|
1955
|
+
}
|
|
1956
|
+
else if (typeof value === 'string') {
|
|
1957
|
+
return value;
|
|
1958
|
+
}
|
|
1959
|
+
else if (typeof value === 'number') {
|
|
1960
|
+
return numberToString(value);
|
|
1961
|
+
}
|
|
1962
|
+
else if (value instanceof Date) {
|
|
1963
|
+
return value.toISOString();
|
|
1964
|
+
}
|
|
1965
|
+
else {
|
|
1966
|
+
return JSON.stringify(value);
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
catch (error) {
|
|
1970
|
+
if (!(error instanceof Error)) {
|
|
1971
|
+
throw error;
|
|
1972
|
+
}
|
|
1973
|
+
console.error(error);
|
|
1974
|
+
return VALUE_STRINGS.unserializable;
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
|
|
2444
1978
|
/**
|
|
2445
1979
|
* Serializes an error into a [🚉] JSON-serializable object
|
|
2446
1980
|
*
|
|
@@ -2459,47 +1993,175 @@ function serializeError(error) {
|
|
|
2459
1993
|
}
|
|
2460
1994
|
|
|
2461
1995
|
/**
|
|
2462
|
-
*
|
|
1996
|
+
* Represents the usage with no resources consumed
|
|
2463
1997
|
*
|
|
2464
|
-
* @
|
|
2465
|
-
* @returns the list of variable names
|
|
2466
|
-
* @throws {ParseError} if the script is invalid
|
|
2467
|
-
* @public exported from `@promptbook/utils` <- Note: [👖] This is usable elsewhere than in Promptbook, so keeping in utils
|
|
1998
|
+
* @public exported from `@promptbook/core`
|
|
2468
1999
|
*/
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2000
|
+
var ZERO_USAGE = $deepFreeze({
|
|
2001
|
+
price: { value: 0 },
|
|
2002
|
+
input: {
|
|
2003
|
+
tokensCount: { value: 0 },
|
|
2004
|
+
charactersCount: { value: 0 },
|
|
2005
|
+
wordsCount: { value: 0 },
|
|
2006
|
+
sentencesCount: { value: 0 },
|
|
2007
|
+
linesCount: { value: 0 },
|
|
2008
|
+
paragraphsCount: { value: 0 },
|
|
2009
|
+
pagesCount: { value: 0 },
|
|
2010
|
+
},
|
|
2011
|
+
output: {
|
|
2012
|
+
tokensCount: { value: 0 },
|
|
2013
|
+
charactersCount: { value: 0 },
|
|
2014
|
+
wordsCount: { value: 0 },
|
|
2015
|
+
sentencesCount: { value: 0 },
|
|
2016
|
+
linesCount: { value: 0 },
|
|
2017
|
+
paragraphsCount: { value: 0 },
|
|
2018
|
+
pagesCount: { value: 0 },
|
|
2019
|
+
},
|
|
2020
|
+
});
|
|
2021
|
+
/**
|
|
2022
|
+
* Represents the usage with unknown resources consumed
|
|
2023
|
+
*
|
|
2024
|
+
* @public exported from `@promptbook/core`
|
|
2025
|
+
*/
|
|
2026
|
+
$deepFreeze({
|
|
2027
|
+
price: { value: 0, isUncertain: true },
|
|
2028
|
+
input: {
|
|
2029
|
+
tokensCount: { value: 0, isUncertain: true },
|
|
2030
|
+
charactersCount: { value: 0, isUncertain: true },
|
|
2031
|
+
wordsCount: { value: 0, isUncertain: true },
|
|
2032
|
+
sentencesCount: { value: 0, isUncertain: true },
|
|
2033
|
+
linesCount: { value: 0, isUncertain: true },
|
|
2034
|
+
paragraphsCount: { value: 0, isUncertain: true },
|
|
2035
|
+
pagesCount: { value: 0, isUncertain: true },
|
|
2036
|
+
},
|
|
2037
|
+
output: {
|
|
2038
|
+
tokensCount: { value: 0, isUncertain: true },
|
|
2039
|
+
charactersCount: { value: 0, isUncertain: true },
|
|
2040
|
+
wordsCount: { value: 0, isUncertain: true },
|
|
2041
|
+
sentencesCount: { value: 0, isUncertain: true },
|
|
2042
|
+
linesCount: { value: 0, isUncertain: true },
|
|
2043
|
+
paragraphsCount: { value: 0, isUncertain: true },
|
|
2044
|
+
pagesCount: { value: 0, isUncertain: true },
|
|
2045
|
+
},
|
|
2046
|
+
});
|
|
2047
|
+
/**
|
|
2048
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
2049
|
+
*/
|
|
2050
|
+
|
|
2051
|
+
/**
|
|
2052
|
+
* Function `addUsage` will add multiple usages into one
|
|
2053
|
+
*
|
|
2054
|
+
* Note: If you provide 0 values, it returns ZERO_USAGE
|
|
2055
|
+
*
|
|
2056
|
+
* @public exported from `@promptbook/core`
|
|
2057
|
+
*/
|
|
2058
|
+
function addUsage() {
|
|
2059
|
+
var usageItems = [];
|
|
2060
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
2061
|
+
usageItems[_i] = arguments[_i];
|
|
2062
|
+
}
|
|
2063
|
+
return usageItems.reduce(function (acc, item) {
|
|
2064
|
+
var e_1, _a, e_2, _b;
|
|
2065
|
+
var _c;
|
|
2066
|
+
acc.price.value += ((_c = item.price) === null || _c === void 0 ? void 0 : _c.value) || 0;
|
|
2067
|
+
try {
|
|
2068
|
+
for (var _d = __values(Object.keys(acc.input)), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
2069
|
+
var key = _e.value;
|
|
2070
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2071
|
+
//@ts-ignore
|
|
2072
|
+
if (item.input[key]) {
|
|
2073
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2074
|
+
//@ts-ignore
|
|
2075
|
+
acc.input[key].value += item.input[key].value || 0;
|
|
2076
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2077
|
+
//@ts-ignore
|
|
2078
|
+
if (item.input[key].isUncertain) {
|
|
2079
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2080
|
+
//@ts-ignore
|
|
2081
|
+
acc.input[key].isUncertain = true;
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
2087
|
+
finally {
|
|
2088
|
+
try {
|
|
2089
|
+
if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
|
|
2090
|
+
}
|
|
2091
|
+
finally { if (e_1) throw e_1.error; }
|
|
2092
|
+
}
|
|
2093
|
+
try {
|
|
2094
|
+
for (var _f = __values(Object.keys(acc.output)), _g = _f.next(); !_g.done; _g = _f.next()) {
|
|
2095
|
+
var key = _g.value;
|
|
2096
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2097
|
+
//@ts-ignore
|
|
2098
|
+
if (item.output[key]) {
|
|
2099
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2100
|
+
//@ts-ignore
|
|
2101
|
+
acc.output[key].value += item.output[key].value || 0;
|
|
2102
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2103
|
+
//@ts-ignore
|
|
2104
|
+
if (item.output[key].isUncertain) {
|
|
2105
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2106
|
+
//@ts-ignore
|
|
2107
|
+
acc.output[key].isUncertain = true;
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
2113
|
+
finally {
|
|
2114
|
+
try {
|
|
2115
|
+
if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
|
|
2116
|
+
}
|
|
2117
|
+
finally { if (e_2) throw e_2.error; }
|
|
2118
|
+
}
|
|
2119
|
+
return acc;
|
|
2120
|
+
}, deepClone(ZERO_USAGE));
|
|
2121
|
+
}
|
|
2122
|
+
|
|
2123
|
+
/**
|
|
2124
|
+
* Parses the given script and returns the list of all used variables that are not defined in the script
|
|
2125
|
+
*
|
|
2126
|
+
* @param script from which to extract the variables
|
|
2127
|
+
* @returns the list of variable names
|
|
2128
|
+
* @throws {ParseError} if the script is invalid
|
|
2129
|
+
* @public exported from `@promptbook/utils` <- Note: [👖] This is usable elsewhere than in Promptbook, so keeping in utils
|
|
2130
|
+
*/
|
|
2131
|
+
function extractVariablesFromScript(script) {
|
|
2132
|
+
var variables = new Set();
|
|
2133
|
+
var originalScript = script;
|
|
2134
|
+
script = "(()=>{".concat(script, "})()");
|
|
2135
|
+
try {
|
|
2136
|
+
for (var i = 0; i < 100 /* <- TODO: This limit to configuration */; i++)
|
|
2137
|
+
try {
|
|
2138
|
+
eval(script);
|
|
2139
|
+
}
|
|
2140
|
+
catch (error) {
|
|
2141
|
+
if (!(error instanceof ReferenceError)) {
|
|
2142
|
+
throw error;
|
|
2143
|
+
}
|
|
2144
|
+
/*
|
|
2145
|
+
Note: Parsing the error
|
|
2146
|
+
🌟 Most devices:
|
|
2147
|
+
[PipelineUrlError: thing is not defined]
|
|
2148
|
+
|
|
2149
|
+
🍏 iPhone`s Safari:
|
|
2150
|
+
[PipelineUrlError: Can't find variable: thing]
|
|
2151
|
+
*/
|
|
2152
|
+
var variableName = undefined;
|
|
2153
|
+
if (error.message.startsWith("Can't")) {
|
|
2154
|
+
// 🍏 Case
|
|
2155
|
+
variableName = error.message.split(' ').pop();
|
|
2156
|
+
}
|
|
2157
|
+
else {
|
|
2158
|
+
// 🌟 Case
|
|
2159
|
+
variableName = error.message.split(' ').shift();
|
|
2160
|
+
}
|
|
2161
|
+
if (variableName === undefined) {
|
|
2162
|
+
throw error;
|
|
2163
|
+
}
|
|
2164
|
+
if (script.includes(variableName + '(')) {
|
|
2503
2165
|
script = "const ".concat(variableName, " = ()=>'';") + script;
|
|
2504
2166
|
}
|
|
2505
2167
|
else {
|
|
@@ -2512,7 +2174,7 @@ function extractVariablesFromScript(script) {
|
|
|
2512
2174
|
if (!(error instanceof Error)) {
|
|
2513
2175
|
throw error;
|
|
2514
2176
|
}
|
|
2515
|
-
throw new ParseError(spaceTrim$1(function (block) { return "\n Can not extract variables from the script\n
|
|
2177
|
+
throw new ParseError(spaceTrim$1(function (block) { return "\n Can not extract variables from the script\n ".concat(block(error.stack || error.message), "\n\n Found variables:\n ").concat(Array.from(variables)
|
|
2516
2178
|
.map(function (variableName, i) { return "".concat(i + 1, ") ").concat(variableName); })
|
|
2517
2179
|
.join('\n'), "\n\n\n The script:\n\n ```javascript\n ").concat(block(originalScript), "\n ```\n "); }));
|
|
2518
2180
|
}
|
|
@@ -2792,27 +2454,6 @@ var CsvFormatDefinition = {
|
|
|
2792
2454
|
* TODO: [🏢] Allow to expect something inside CSV objects and other formats
|
|
2793
2455
|
*/
|
|
2794
2456
|
|
|
2795
|
-
/**
|
|
2796
|
-
* Function isValidJsonString will tell you if the string is valid JSON or not
|
|
2797
|
-
*
|
|
2798
|
-
* @public exported from `@promptbook/utils`
|
|
2799
|
-
*/
|
|
2800
|
-
function isValidJsonString(value /* <- [👨⚖️] */) {
|
|
2801
|
-
try {
|
|
2802
|
-
JSON.parse(value);
|
|
2803
|
-
return true;
|
|
2804
|
-
}
|
|
2805
|
-
catch (error) {
|
|
2806
|
-
if (!(error instanceof Error)) {
|
|
2807
|
-
throw error;
|
|
2808
|
-
}
|
|
2809
|
-
if (error.message.includes('Unexpected token')) {
|
|
2810
|
-
return false;
|
|
2811
|
-
}
|
|
2812
|
-
return false;
|
|
2813
|
-
}
|
|
2814
|
-
}
|
|
2815
|
-
|
|
2816
2457
|
/**
|
|
2817
2458
|
* Definition for JSON format
|
|
2818
2459
|
*
|
|
@@ -2883,137 +2524,429 @@ var TextFormatDefinition = {
|
|
|
2883
2524
|
mappedLines = _a.sent();
|
|
2884
2525
|
return [2 /*return*/, mappedLines.join('\n')];
|
|
2885
2526
|
}
|
|
2886
|
-
});
|
|
2887
|
-
});
|
|
2888
|
-
},
|
|
2889
|
-
},
|
|
2890
|
-
// <- TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
|
|
2891
|
-
],
|
|
2892
|
-
};
|
|
2527
|
+
});
|
|
2528
|
+
});
|
|
2529
|
+
},
|
|
2530
|
+
},
|
|
2531
|
+
// <- TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
|
|
2532
|
+
],
|
|
2533
|
+
};
|
|
2534
|
+
/**
|
|
2535
|
+
* TODO: [1] Make type for XML Text and Schema
|
|
2536
|
+
* TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
|
|
2537
|
+
* TODO: [🍓] In `TextFormatDefinition` implement simple `isValid`
|
|
2538
|
+
* TODO: [🍓] In `TextFormatDefinition` implement partial `canBeValid`
|
|
2539
|
+
* TODO: [🍓] In `TextFormatDefinition` implement `heal
|
|
2540
|
+
* TODO: [🍓] In `TextFormatDefinition` implement `subvalueDefinitions`
|
|
2541
|
+
* TODO: [🏢] Allow to expect something inside each item of list and other formats
|
|
2542
|
+
*/
|
|
2543
|
+
|
|
2544
|
+
/**
|
|
2545
|
+
* Definition for XML format
|
|
2546
|
+
*
|
|
2547
|
+
* @private still in development [🏢]
|
|
2548
|
+
*/
|
|
2549
|
+
var XmlFormatDefinition = {
|
|
2550
|
+
formatName: 'XML',
|
|
2551
|
+
mimeType: 'application/xml',
|
|
2552
|
+
isValid: function (value, settings, schema) {
|
|
2553
|
+
return true;
|
|
2554
|
+
},
|
|
2555
|
+
canBeValid: function (partialValue, settings, schema) {
|
|
2556
|
+
return true;
|
|
2557
|
+
},
|
|
2558
|
+
heal: function (value, settings, schema) {
|
|
2559
|
+
throw new Error('Not implemented');
|
|
2560
|
+
},
|
|
2561
|
+
subvalueDefinitions: [],
|
|
2562
|
+
};
|
|
2563
|
+
/**
|
|
2564
|
+
* TODO: [🧠] Maybe propper instance of object
|
|
2565
|
+
* TODO: [0] Make string_serialized_xml
|
|
2566
|
+
* TODO: [1] Make type for XML Settings and Schema
|
|
2567
|
+
* TODO: [🧠] What to use for validating XMLs - XSD,...
|
|
2568
|
+
* TODO: [🍓] In `XmlFormatDefinition` implement simple `isValid`
|
|
2569
|
+
* TODO: [🍓] In `XmlFormatDefinition` implement partial `canBeValid`
|
|
2570
|
+
* TODO: [🍓] In `XmlFormatDefinition` implement `heal
|
|
2571
|
+
* TODO: [🍓] In `XmlFormatDefinition` implement `subvalueDefinitions`
|
|
2572
|
+
* TODO: [🏢] Allow to expect something inside XML and other formats
|
|
2573
|
+
*/
|
|
2574
|
+
|
|
2575
|
+
/**
|
|
2576
|
+
* Definitions for all formats supported by Promptbook
|
|
2577
|
+
*
|
|
2578
|
+
* @private internal index of `...` <- TODO [🏢]
|
|
2579
|
+
*/
|
|
2580
|
+
var FORMAT_DEFINITIONS = [
|
|
2581
|
+
JsonFormatDefinition,
|
|
2582
|
+
XmlFormatDefinition,
|
|
2583
|
+
TextFormatDefinition,
|
|
2584
|
+
CsvFormatDefinition,
|
|
2585
|
+
];
|
|
2586
|
+
/**
|
|
2587
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
2588
|
+
*/
|
|
2589
|
+
|
|
2590
|
+
/**
|
|
2591
|
+
* Maps available parameters to expected parameters
|
|
2592
|
+
*
|
|
2593
|
+
* The strategy is:
|
|
2594
|
+
* 1) @@@
|
|
2595
|
+
* 2) @@@
|
|
2596
|
+
*
|
|
2597
|
+
* @throws {PipelineExecutionError} @@@
|
|
2598
|
+
* @private within the repository used in `createPipelineExecutor`
|
|
2599
|
+
*/
|
|
2600
|
+
function mapAvailableToExpectedParameters(options) {
|
|
2601
|
+
var e_1, _a;
|
|
2602
|
+
var expectedParameters = options.expectedParameters, availableParameters = options.availableParameters;
|
|
2603
|
+
var availableParametersNames = new Set(Object.keys(availableParameters));
|
|
2604
|
+
var expectedParameterNames = new Set(Object.keys(expectedParameters));
|
|
2605
|
+
var mappedParameters = {};
|
|
2606
|
+
try {
|
|
2607
|
+
// Phase 1️⃣: Matching mapping
|
|
2608
|
+
for (var _b = __values(Array.from(union(availableParametersNames, expectedParameterNames))), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
2609
|
+
var parameterName = _c.value;
|
|
2610
|
+
// Situation: Parameter is available and expected
|
|
2611
|
+
if (availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
|
|
2612
|
+
mappedParameters[parameterName] = availableParameters[parameterName];
|
|
2613
|
+
// <- Note: [👩👩👧] Maybe detect parameter collision here?
|
|
2614
|
+
availableParametersNames.delete(parameterName);
|
|
2615
|
+
expectedParameterNames.delete(parameterName);
|
|
2616
|
+
}
|
|
2617
|
+
// Situation: Parameter is available but NOT expected
|
|
2618
|
+
else if (availableParametersNames.has(parameterName) && !expectedParameterNames.has(parameterName)) {
|
|
2619
|
+
// [🐱👤] Do not pass this parameter to prompt - Maybe use it non-matching mapping
|
|
2620
|
+
}
|
|
2621
|
+
// Situation: Parameter is NOT available BUT expected
|
|
2622
|
+
else if (!availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
|
|
2623
|
+
// Do nothing here - this will be maybe fixed in the non-matching mapping
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
}
|
|
2627
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
2628
|
+
finally {
|
|
2629
|
+
try {
|
|
2630
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
2631
|
+
}
|
|
2632
|
+
finally { if (e_1) throw e_1.error; }
|
|
2633
|
+
}
|
|
2634
|
+
if (expectedParameterNames.size === 0) {
|
|
2635
|
+
// Note: [👨👨👧] Now we can freeze `mappedParameters` to prevent @@@
|
|
2636
|
+
Object.freeze(mappedParameters);
|
|
2637
|
+
return mappedParameters;
|
|
2638
|
+
}
|
|
2639
|
+
// Phase 2️⃣: Non-matching mapping
|
|
2640
|
+
if (expectedParameterNames.size !== availableParametersNames.size) {
|
|
2641
|
+
throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Can not map available parameters to expected parameters\n\n Mapped parameters:\n ".concat(block(Object.keys(mappedParameters)
|
|
2642
|
+
.map(function (parameterName) { return "- {".concat(parameterName, "}"); })
|
|
2643
|
+
.join('\n')), "\n\n Expected parameters which can not be mapped:\n ").concat(block(Array.from(expectedParameterNames)
|
|
2644
|
+
.map(function (parameterName) { return "- {".concat(parameterName, "}"); })
|
|
2645
|
+
.join('\n')), "\n\n Remaining available parameters:\n ").concat(block(Array.from(availableParametersNames)
|
|
2646
|
+
.map(function (parameterName) { return "- {".concat(parameterName, "}"); })
|
|
2647
|
+
.join('\n')), "\n\n "); }));
|
|
2648
|
+
}
|
|
2649
|
+
var expectedParameterNamesArray = Array.from(expectedParameterNames);
|
|
2650
|
+
var availableParametersNamesArray = Array.from(availableParametersNames);
|
|
2651
|
+
for (var i = 0; i < expectedParameterNames.size; i++) {
|
|
2652
|
+
mappedParameters[expectedParameterNamesArray[i]] = availableParameters[availableParametersNamesArray[i]];
|
|
2653
|
+
}
|
|
2654
|
+
// Note: [👨👨👧] Now we can freeze `mappedParameters` to prevent @@@
|
|
2655
|
+
Object.freeze(mappedParameters);
|
|
2656
|
+
return mappedParameters;
|
|
2657
|
+
}
|
|
2658
|
+
|
|
2659
|
+
/**
|
|
2660
|
+
* Multiple LLM Execution Tools is a proxy server that uses multiple execution tools internally and exposes the executor interface externally.
|
|
2661
|
+
*
|
|
2662
|
+
* Note: Internal utility of `joinLlmExecutionTools` but exposed type
|
|
2663
|
+
* @public exported from `@promptbook/core`
|
|
2664
|
+
*/
|
|
2665
|
+
var MultipleLlmExecutionTools = /** @class */ (function () {
|
|
2666
|
+
/**
|
|
2667
|
+
* Gets array of execution tools in order of priority
|
|
2668
|
+
*/
|
|
2669
|
+
function MultipleLlmExecutionTools() {
|
|
2670
|
+
var llmExecutionTools = [];
|
|
2671
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
2672
|
+
llmExecutionTools[_i] = arguments[_i];
|
|
2673
|
+
}
|
|
2674
|
+
this.llmExecutionTools = llmExecutionTools;
|
|
2675
|
+
}
|
|
2676
|
+
Object.defineProperty(MultipleLlmExecutionTools.prototype, "title", {
|
|
2677
|
+
get: function () {
|
|
2678
|
+
return 'Multiple LLM Providers';
|
|
2679
|
+
},
|
|
2680
|
+
enumerable: false,
|
|
2681
|
+
configurable: true
|
|
2682
|
+
});
|
|
2683
|
+
Object.defineProperty(MultipleLlmExecutionTools.prototype, "description", {
|
|
2684
|
+
get: function () {
|
|
2685
|
+
return this.llmExecutionTools.map(function (_a, index) {
|
|
2686
|
+
var title = _a.title;
|
|
2687
|
+
return "".concat(index + 1, ") `").concat(title, "`");
|
|
2688
|
+
}).join('\n');
|
|
2689
|
+
},
|
|
2690
|
+
enumerable: false,
|
|
2691
|
+
configurable: true
|
|
2692
|
+
});
|
|
2693
|
+
/**
|
|
2694
|
+
* Check the configuration of all execution tools
|
|
2695
|
+
*/
|
|
2696
|
+
MultipleLlmExecutionTools.prototype.checkConfiguration = function () {
|
|
2697
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2698
|
+
var _a, _b, llmExecutionTools, e_1_1;
|
|
2699
|
+
var e_1, _c;
|
|
2700
|
+
return __generator(this, function (_d) {
|
|
2701
|
+
switch (_d.label) {
|
|
2702
|
+
case 0:
|
|
2703
|
+
_d.trys.push([0, 5, 6, 7]);
|
|
2704
|
+
_a = __values(this.llmExecutionTools), _b = _a.next();
|
|
2705
|
+
_d.label = 1;
|
|
2706
|
+
case 1:
|
|
2707
|
+
if (!!_b.done) return [3 /*break*/, 4];
|
|
2708
|
+
llmExecutionTools = _b.value;
|
|
2709
|
+
return [4 /*yield*/, llmExecutionTools.checkConfiguration()];
|
|
2710
|
+
case 2:
|
|
2711
|
+
_d.sent();
|
|
2712
|
+
_d.label = 3;
|
|
2713
|
+
case 3:
|
|
2714
|
+
_b = _a.next();
|
|
2715
|
+
return [3 /*break*/, 1];
|
|
2716
|
+
case 4: return [3 /*break*/, 7];
|
|
2717
|
+
case 5:
|
|
2718
|
+
e_1_1 = _d.sent();
|
|
2719
|
+
e_1 = { error: e_1_1 };
|
|
2720
|
+
return [3 /*break*/, 7];
|
|
2721
|
+
case 6:
|
|
2722
|
+
try {
|
|
2723
|
+
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
2724
|
+
}
|
|
2725
|
+
finally { if (e_1) throw e_1.error; }
|
|
2726
|
+
return [7 /*endfinally*/];
|
|
2727
|
+
case 7: return [2 /*return*/];
|
|
2728
|
+
}
|
|
2729
|
+
});
|
|
2730
|
+
});
|
|
2731
|
+
};
|
|
2732
|
+
/**
|
|
2733
|
+
* List all available models that can be used
|
|
2734
|
+
* This lists is a combination of all available models from all execution tools
|
|
2735
|
+
*/
|
|
2736
|
+
MultipleLlmExecutionTools.prototype.listModels = function () {
|
|
2737
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2738
|
+
var availableModels, _a, _b, llmExecutionTools, models, e_2_1;
|
|
2739
|
+
var e_2, _c;
|
|
2740
|
+
return __generator(this, function (_d) {
|
|
2741
|
+
switch (_d.label) {
|
|
2742
|
+
case 0:
|
|
2743
|
+
availableModels = [];
|
|
2744
|
+
_d.label = 1;
|
|
2745
|
+
case 1:
|
|
2746
|
+
_d.trys.push([1, 6, 7, 8]);
|
|
2747
|
+
_a = __values(this.llmExecutionTools), _b = _a.next();
|
|
2748
|
+
_d.label = 2;
|
|
2749
|
+
case 2:
|
|
2750
|
+
if (!!_b.done) return [3 /*break*/, 5];
|
|
2751
|
+
llmExecutionTools = _b.value;
|
|
2752
|
+
return [4 /*yield*/, llmExecutionTools.listModels()];
|
|
2753
|
+
case 3:
|
|
2754
|
+
models = _d.sent();
|
|
2755
|
+
availableModels.push.apply(availableModels, __spreadArray([], __read(models), false));
|
|
2756
|
+
_d.label = 4;
|
|
2757
|
+
case 4:
|
|
2758
|
+
_b = _a.next();
|
|
2759
|
+
return [3 /*break*/, 2];
|
|
2760
|
+
case 5: return [3 /*break*/, 8];
|
|
2761
|
+
case 6:
|
|
2762
|
+
e_2_1 = _d.sent();
|
|
2763
|
+
e_2 = { error: e_2_1 };
|
|
2764
|
+
return [3 /*break*/, 8];
|
|
2765
|
+
case 7:
|
|
2766
|
+
try {
|
|
2767
|
+
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
2768
|
+
}
|
|
2769
|
+
finally { if (e_2) throw e_2.error; }
|
|
2770
|
+
return [7 /*endfinally*/];
|
|
2771
|
+
case 8: return [2 /*return*/, availableModels];
|
|
2772
|
+
}
|
|
2773
|
+
});
|
|
2774
|
+
});
|
|
2775
|
+
};
|
|
2776
|
+
/**
|
|
2777
|
+
* Calls the best available chat model
|
|
2778
|
+
*/
|
|
2779
|
+
MultipleLlmExecutionTools.prototype.callChatModel = function (prompt) {
|
|
2780
|
+
return this.callCommonModel(prompt);
|
|
2781
|
+
};
|
|
2782
|
+
/**
|
|
2783
|
+
* Calls the best available completion model
|
|
2784
|
+
*/
|
|
2785
|
+
MultipleLlmExecutionTools.prototype.callCompletionModel = function (prompt) {
|
|
2786
|
+
return this.callCommonModel(prompt);
|
|
2787
|
+
};
|
|
2788
|
+
/**
|
|
2789
|
+
* Calls the best available embedding model
|
|
2790
|
+
*/
|
|
2791
|
+
MultipleLlmExecutionTools.prototype.callEmbeddingModel = function (prompt) {
|
|
2792
|
+
return this.callCommonModel(prompt);
|
|
2793
|
+
};
|
|
2794
|
+
// <- Note: [🤖]
|
|
2795
|
+
/**
|
|
2796
|
+
* Calls the best available model
|
|
2797
|
+
*
|
|
2798
|
+
* Note: This should be private or protected but is public to be usable with duck typing
|
|
2799
|
+
*/
|
|
2800
|
+
MultipleLlmExecutionTools.prototype.callCommonModel = function (prompt) {
|
|
2801
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2802
|
+
var errors, _a, _b, llmExecutionTools, _c, error_1, e_3_1;
|
|
2803
|
+
var e_3, _d;
|
|
2804
|
+
var _this = this;
|
|
2805
|
+
return __generator(this, function (_e) {
|
|
2806
|
+
switch (_e.label) {
|
|
2807
|
+
case 0:
|
|
2808
|
+
errors = [];
|
|
2809
|
+
_e.label = 1;
|
|
2810
|
+
case 1:
|
|
2811
|
+
_e.trys.push([1, 15, 16, 17]);
|
|
2812
|
+
_a = __values(this.llmExecutionTools), _b = _a.next();
|
|
2813
|
+
_e.label = 2;
|
|
2814
|
+
case 2:
|
|
2815
|
+
if (!!_b.done) return [3 /*break*/, 14];
|
|
2816
|
+
llmExecutionTools = _b.value;
|
|
2817
|
+
_e.label = 3;
|
|
2818
|
+
case 3:
|
|
2819
|
+
_e.trys.push([3, 12, , 13]);
|
|
2820
|
+
_c = prompt.modelRequirements.modelVariant;
|
|
2821
|
+
switch (_c) {
|
|
2822
|
+
case 'CHAT': return [3 /*break*/, 4];
|
|
2823
|
+
case 'COMPLETION': return [3 /*break*/, 6];
|
|
2824
|
+
case 'EMBEDDING': return [3 /*break*/, 8];
|
|
2825
|
+
}
|
|
2826
|
+
return [3 /*break*/, 10];
|
|
2827
|
+
case 4:
|
|
2828
|
+
if (llmExecutionTools.callChatModel === undefined) {
|
|
2829
|
+
return [3 /*break*/, 13];
|
|
2830
|
+
}
|
|
2831
|
+
return [4 /*yield*/, llmExecutionTools.callChatModel(prompt)];
|
|
2832
|
+
case 5: return [2 /*return*/, _e.sent()];
|
|
2833
|
+
case 6:
|
|
2834
|
+
if (llmExecutionTools.callCompletionModel === undefined) {
|
|
2835
|
+
return [3 /*break*/, 13];
|
|
2836
|
+
}
|
|
2837
|
+
return [4 /*yield*/, llmExecutionTools.callCompletionModel(prompt)];
|
|
2838
|
+
case 7: return [2 /*return*/, _e.sent()];
|
|
2839
|
+
case 8:
|
|
2840
|
+
if (llmExecutionTools.callEmbeddingModel === undefined) {
|
|
2841
|
+
return [3 /*break*/, 13];
|
|
2842
|
+
}
|
|
2843
|
+
return [4 /*yield*/, llmExecutionTools.callEmbeddingModel(prompt)];
|
|
2844
|
+
case 9: return [2 /*return*/, _e.sent()];
|
|
2845
|
+
case 10: throw new UnexpectedError("Unknown model variant \"".concat(prompt.modelRequirements.modelVariant, "\""));
|
|
2846
|
+
case 11: return [3 /*break*/, 13];
|
|
2847
|
+
case 12:
|
|
2848
|
+
error_1 = _e.sent();
|
|
2849
|
+
if (!(error_1 instanceof Error) || error_1 instanceof UnexpectedError) {
|
|
2850
|
+
throw error_1;
|
|
2851
|
+
}
|
|
2852
|
+
errors.push(error_1);
|
|
2853
|
+
return [3 /*break*/, 13];
|
|
2854
|
+
case 13:
|
|
2855
|
+
_b = _a.next();
|
|
2856
|
+
return [3 /*break*/, 2];
|
|
2857
|
+
case 14: return [3 /*break*/, 17];
|
|
2858
|
+
case 15:
|
|
2859
|
+
e_3_1 = _e.sent();
|
|
2860
|
+
e_3 = { error: e_3_1 };
|
|
2861
|
+
return [3 /*break*/, 17];
|
|
2862
|
+
case 16:
|
|
2863
|
+
try {
|
|
2864
|
+
if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
|
|
2865
|
+
}
|
|
2866
|
+
finally { if (e_3) throw e_3.error; }
|
|
2867
|
+
return [7 /*endfinally*/];
|
|
2868
|
+
case 17:
|
|
2869
|
+
if (errors.length === 1) {
|
|
2870
|
+
throw errors[0];
|
|
2871
|
+
}
|
|
2872
|
+
else if (errors.length > 1) {
|
|
2873
|
+
throw new PipelineExecutionError(
|
|
2874
|
+
// TODO: Tell which execution tools failed like
|
|
2875
|
+
// 1) OpenAI throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
2876
|
+
// 2) AnthropicClaude throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
2877
|
+
// 3) ...
|
|
2878
|
+
spaceTrim(function (block) { return "\n All execution tools failed:\n\n ".concat(block(errors
|
|
2879
|
+
.map(function (error, i) { return "".concat(i + 1, ") **").concat(error.name || 'Error', ":** ").concat(error.message); })
|
|
2880
|
+
.join('\n')), "\n\n "); }));
|
|
2881
|
+
}
|
|
2882
|
+
else if (this.llmExecutionTools.length === 0) {
|
|
2883
|
+
throw new PipelineExecutionError("You have not provided any `LlmExecutionTools`");
|
|
2884
|
+
}
|
|
2885
|
+
else {
|
|
2886
|
+
throw new PipelineExecutionError(spaceTrim(function (block) { return "\n You have not provided any `LlmExecutionTools` that support model variant \"".concat(prompt.modelRequirements.modelVariant, "\"\n\n Available `LlmExecutionTools`:\n ").concat(block(_this.description), "\n\n "); }));
|
|
2887
|
+
}
|
|
2888
|
+
}
|
|
2889
|
+
});
|
|
2890
|
+
});
|
|
2891
|
+
};
|
|
2892
|
+
return MultipleLlmExecutionTools;
|
|
2893
|
+
}());
|
|
2893
2894
|
/**
|
|
2894
|
-
* TODO: [
|
|
2895
|
-
* TODO: [
|
|
2896
|
-
*
|
|
2897
|
-
* TODO: [🍓] In `TextFormatDefinition` implement partial `canBeValid`
|
|
2898
|
-
* TODO: [🍓] In `TextFormatDefinition` implement `heal
|
|
2899
|
-
* TODO: [🍓] In `TextFormatDefinition` implement `subvalueDefinitions`
|
|
2900
|
-
* TODO: [🏢] Allow to expect something inside each item of list and other formats
|
|
2895
|
+
* TODO: [🧠][🎛] Aggregating multiple models - have result not only from one first aviable model BUT all of them
|
|
2896
|
+
* TODO: [🏖] If no llmTools have for example not defined `callCompletionModel` this will still return object with defined `callCompletionModel` which just throws `PipelineExecutionError`, make it undefined instead
|
|
2897
|
+
* Look how `countTotalUsage` (and `cacheLlmTools`) implements it
|
|
2901
2898
|
*/
|
|
2902
2899
|
|
|
2903
2900
|
/**
|
|
2904
|
-
*
|
|
2901
|
+
* Joins multiple LLM Execution Tools into one
|
|
2905
2902
|
*
|
|
2906
|
-
* @
|
|
2907
|
-
*/
|
|
2908
|
-
var XmlFormatDefinition = {
|
|
2909
|
-
formatName: 'XML',
|
|
2910
|
-
mimeType: 'application/xml',
|
|
2911
|
-
isValid: function (value, settings, schema) {
|
|
2912
|
-
return true;
|
|
2913
|
-
},
|
|
2914
|
-
canBeValid: function (partialValue, settings, schema) {
|
|
2915
|
-
return true;
|
|
2916
|
-
},
|
|
2917
|
-
heal: function (value, settings, schema) {
|
|
2918
|
-
throw new Error('Not implemented');
|
|
2919
|
-
},
|
|
2920
|
-
subvalueDefinitions: [],
|
|
2921
|
-
};
|
|
2922
|
-
/**
|
|
2923
|
-
* TODO: [🧠] Maybe propper instance of object
|
|
2924
|
-
* TODO: [0] Make string_serialized_xml
|
|
2925
|
-
* TODO: [1] Make type for XML Settings and Schema
|
|
2926
|
-
* TODO: [🧠] What to use for validating XMLs - XSD,...
|
|
2927
|
-
* TODO: [🍓] In `XmlFormatDefinition` implement simple `isValid`
|
|
2928
|
-
* TODO: [🍓] In `XmlFormatDefinition` implement partial `canBeValid`
|
|
2929
|
-
* TODO: [🍓] In `XmlFormatDefinition` implement `heal
|
|
2930
|
-
* TODO: [🍓] In `XmlFormatDefinition` implement `subvalueDefinitions`
|
|
2931
|
-
* TODO: [🏢] Allow to expect something inside XML and other formats
|
|
2932
|
-
*/
|
|
2933
|
-
|
|
2934
|
-
/**
|
|
2935
|
-
* Definitions for all formats supported by Promptbook
|
|
2903
|
+
* @returns {LlmExecutionTools} Single wrapper for multiple LlmExecutionTools
|
|
2936
2904
|
*
|
|
2937
|
-
*
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
XmlFormatDefinition,
|
|
2942
|
-
TextFormatDefinition,
|
|
2943
|
-
CsvFormatDefinition,
|
|
2944
|
-
];
|
|
2945
|
-
/**
|
|
2946
|
-
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
2947
|
-
*/
|
|
2948
|
-
|
|
2949
|
-
/**
|
|
2950
|
-
* Maps available parameters to expected parameters
|
|
2905
|
+
* 0) If there is no LlmExecutionTools, it warns and returns valid but empty LlmExecutionTools
|
|
2906
|
+
* 1) If there is only one LlmExecutionTools, it returns it wrapped in a proxy object
|
|
2907
|
+
* 2) If there are multiple LlmExecutionTools, first will be used first, second will be used if the first hasn`t defined model variant or fails, etc.
|
|
2908
|
+
* 3) When all LlmExecutionTools fail, it throws an error with a list of all errors merged into one
|
|
2951
2909
|
*
|
|
2952
|
-
* The strategy is:
|
|
2953
|
-
* 1) @@@
|
|
2954
|
-
* 2) @@@
|
|
2955
2910
|
*
|
|
2956
|
-
*
|
|
2957
|
-
*
|
|
2911
|
+
* Tip: You don't have to use this function directly, just pass an array of LlmExecutionTools to the `ExecutionTools`
|
|
2912
|
+
*
|
|
2913
|
+
* @public exported from `@promptbook/core`
|
|
2958
2914
|
*/
|
|
2959
|
-
function
|
|
2960
|
-
var
|
|
2961
|
-
var
|
|
2962
|
-
|
|
2963
|
-
var expectedParameterNames = new Set(Object.keys(expectedParameters));
|
|
2964
|
-
var mappedParameters = {};
|
|
2965
|
-
try {
|
|
2966
|
-
// Phase 1️⃣: Matching mapping
|
|
2967
|
-
for (var _b = __values(Array.from(union(availableParametersNames, expectedParameterNames))), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
2968
|
-
var parameterName = _c.value;
|
|
2969
|
-
// Situation: Parameter is available and expected
|
|
2970
|
-
if (availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
|
|
2971
|
-
mappedParameters[parameterName] = availableParameters[parameterName];
|
|
2972
|
-
// <- Note: [👩👩👧] Maybe detect parameter collision here?
|
|
2973
|
-
availableParametersNames.delete(parameterName);
|
|
2974
|
-
expectedParameterNames.delete(parameterName);
|
|
2975
|
-
}
|
|
2976
|
-
// Situation: Parameter is available but NOT expected
|
|
2977
|
-
else if (availableParametersNames.has(parameterName) && !expectedParameterNames.has(parameterName)) {
|
|
2978
|
-
// [🐱👤] Do not pass this parameter to prompt - Maybe use it non-matching mapping
|
|
2979
|
-
}
|
|
2980
|
-
// Situation: Parameter is NOT available BUT expected
|
|
2981
|
-
else if (!availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
|
|
2982
|
-
// Do nothing here - this will be maybe fixed in the non-matching mapping
|
|
2983
|
-
}
|
|
2984
|
-
}
|
|
2985
|
-
}
|
|
2986
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
2987
|
-
finally {
|
|
2988
|
-
try {
|
|
2989
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
2990
|
-
}
|
|
2991
|
-
finally { if (e_1) throw e_1.error; }
|
|
2992
|
-
}
|
|
2993
|
-
if (expectedParameterNames.size === 0) {
|
|
2994
|
-
// Note: [👨👨👧] Now we can freeze `mappedParameters` to prevent @@@
|
|
2995
|
-
Object.freeze(mappedParameters);
|
|
2996
|
-
return mappedParameters;
|
|
2997
|
-
}
|
|
2998
|
-
// Phase 2️⃣: Non-matching mapping
|
|
2999
|
-
if (expectedParameterNames.size !== availableParametersNames.size) {
|
|
3000
|
-
throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Can not map available parameters to expected parameters\n\n Mapped parameters:\n ".concat(block(Object.keys(mappedParameters)
|
|
3001
|
-
.map(function (parameterName) { return "- {".concat(parameterName, "}"); })
|
|
3002
|
-
.join('\n')), "\n\n Expected parameters which can not be mapped:\n ").concat(block(Array.from(expectedParameterNames)
|
|
3003
|
-
.map(function (parameterName) { return "- {".concat(parameterName, "}"); })
|
|
3004
|
-
.join('\n')), "\n\n Remaining available parameters:\n ").concat(block(Array.from(availableParametersNames)
|
|
3005
|
-
.map(function (parameterName) { return "- {".concat(parameterName, "}"); })
|
|
3006
|
-
.join('\n')), "\n\n "); }));
|
|
2915
|
+
function joinLlmExecutionTools() {
|
|
2916
|
+
var llmExecutionTools = [];
|
|
2917
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
2918
|
+
llmExecutionTools[_i] = arguments[_i];
|
|
3007
2919
|
}
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
2920
|
+
if (llmExecutionTools.length === 0) {
|
|
2921
|
+
var warningMessage = spaceTrim("\n You have not provided any `LlmExecutionTools`\n This means that you won't be able to execute any prompts that require large language models like GPT-4 or Anthropic's Claude.\n\n 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.\n ");
|
|
2922
|
+
// TODO: [🟥] Detect browser / node and make it colorfull
|
|
2923
|
+
console.warn(warningMessage);
|
|
2924
|
+
/*
|
|
2925
|
+
return {
|
|
2926
|
+
async listModels() {
|
|
2927
|
+
// TODO: [🟥] Detect browser / node and make it colorfull
|
|
2928
|
+
console.warn(
|
|
2929
|
+
spaceTrim(
|
|
2930
|
+
(block) => `
|
|
2931
|
+
|
|
2932
|
+
You can't list models because you have no LLM Execution Tools defined:
|
|
2933
|
+
|
|
2934
|
+
tl;dr
|
|
2935
|
+
|
|
2936
|
+
${block(warningMessage)}
|
|
2937
|
+
`,
|
|
2938
|
+
),
|
|
2939
|
+
);
|
|
2940
|
+
return [];
|
|
2941
|
+
},
|
|
2942
|
+
};
|
|
2943
|
+
*/
|
|
3012
2944
|
}
|
|
3013
|
-
|
|
3014
|
-
Object.freeze(mappedParameters);
|
|
3015
|
-
return mappedParameters;
|
|
2945
|
+
return new (MultipleLlmExecutionTools.bind.apply(MultipleLlmExecutionTools, __spreadArray([void 0], __read(llmExecutionTools), false)))();
|
|
3016
2946
|
}
|
|
2947
|
+
/**
|
|
2948
|
+
* TODO: [👷♂️] @@@ Manual about construction of llmTools
|
|
2949
|
+
*/
|
|
3017
2950
|
|
|
3018
2951
|
/**
|
|
3019
2952
|
* Extracts all code blocks from markdown.
|
|
@@ -3132,97 +3065,22 @@ function extractJsonBlock(markdown) {
|
|
|
3132
3065
|
*/
|
|
3133
3066
|
|
|
3134
3067
|
/**
|
|
3135
|
-
* Takes an item or an array of items and returns an array of items
|
|
3136
|
-
*
|
|
3137
|
-
* 1) Any item except array and undefined returns array with that one item (also null)
|
|
3138
|
-
* 2) Undefined returns empty array
|
|
3139
|
-
* 3) Array returns itself
|
|
3140
|
-
*
|
|
3141
|
-
* @private internal utility
|
|
3142
|
-
*/
|
|
3143
|
-
function arrayableToArray(input) {
|
|
3144
|
-
if (input === undefined) {
|
|
3145
|
-
return [];
|
|
3146
|
-
}
|
|
3147
|
-
if (input instanceof Array) {
|
|
3148
|
-
return input;
|
|
3149
|
-
}
|
|
3150
|
-
return [input];
|
|
3151
|
-
}
|
|
3152
|
-
|
|
3153
|
-
/**
|
|
3154
|
-
* Format either small or big number
|
|
3155
|
-
*
|
|
3156
|
-
* @public exported from `@promptbook/utils`
|
|
3157
|
-
*/
|
|
3158
|
-
function numberToString(value) {
|
|
3159
|
-
if (value === 0) {
|
|
3160
|
-
return '0';
|
|
3161
|
-
}
|
|
3162
|
-
else if (Number.isNaN(value)) {
|
|
3163
|
-
return VALUE_STRINGS.nan;
|
|
3164
|
-
}
|
|
3165
|
-
else if (value === Infinity) {
|
|
3166
|
-
return VALUE_STRINGS.infinity;
|
|
3167
|
-
}
|
|
3168
|
-
else if (value === -Infinity) {
|
|
3169
|
-
return VALUE_STRINGS.negativeInfinity;
|
|
3170
|
-
}
|
|
3171
|
-
for (var exponent = 0; exponent < 15; exponent++) {
|
|
3172
|
-
var factor = Math.pow(10, exponent);
|
|
3173
|
-
var valueRounded = Math.round(value * factor) / factor;
|
|
3174
|
-
if (Math.abs(value - valueRounded) / value < SMALL_NUMBER) {
|
|
3175
|
-
return valueRounded.toFixed(exponent);
|
|
3176
|
-
}
|
|
3177
|
-
}
|
|
3178
|
-
return value.toString();
|
|
3179
|
-
}
|
|
3180
|
-
|
|
3181
|
-
/**
|
|
3182
|
-
* Function `valueToString` will convert the given value to string
|
|
3183
|
-
* This is useful and used in the `templateParameters` function
|
|
3184
|
-
*
|
|
3185
|
-
* Note: This function is not just calling `toString` method
|
|
3186
|
-
* It's more complex and can handle this conversion specifically for LLM models
|
|
3187
|
-
* See `VALUE_STRINGS`
|
|
3068
|
+
* Takes an item or an array of items and returns an array of items
|
|
3188
3069
|
*
|
|
3189
|
-
*
|
|
3190
|
-
*
|
|
3191
|
-
*
|
|
3070
|
+
* 1) Any item except array and undefined returns array with that one item (also null)
|
|
3071
|
+
* 2) Undefined returns empty array
|
|
3072
|
+
* 3) Array returns itself
|
|
3192
3073
|
*
|
|
3193
|
-
* @
|
|
3074
|
+
* @private internal utility
|
|
3194
3075
|
*/
|
|
3195
|
-
function
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
return VALUE_STRINGS.empty;
|
|
3199
|
-
}
|
|
3200
|
-
else if (value === null) {
|
|
3201
|
-
return VALUE_STRINGS.null;
|
|
3202
|
-
}
|
|
3203
|
-
else if (value === undefined) {
|
|
3204
|
-
return VALUE_STRINGS.undefined;
|
|
3205
|
-
}
|
|
3206
|
-
else if (typeof value === 'string') {
|
|
3207
|
-
return value;
|
|
3208
|
-
}
|
|
3209
|
-
else if (typeof value === 'number') {
|
|
3210
|
-
return numberToString(value);
|
|
3211
|
-
}
|
|
3212
|
-
else if (value instanceof Date) {
|
|
3213
|
-
return value.toISOString();
|
|
3214
|
-
}
|
|
3215
|
-
else {
|
|
3216
|
-
return JSON.stringify(value);
|
|
3217
|
-
}
|
|
3076
|
+
function arrayableToArray(input) {
|
|
3077
|
+
if (input === undefined) {
|
|
3078
|
+
return [];
|
|
3218
3079
|
}
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
throw error;
|
|
3222
|
-
}
|
|
3223
|
-
console.error(error);
|
|
3224
|
-
return VALUE_STRINGS.unserializable;
|
|
3080
|
+
if (input instanceof Array) {
|
|
3081
|
+
return input;
|
|
3225
3082
|
}
|
|
3083
|
+
return [input];
|
|
3226
3084
|
}
|
|
3227
3085
|
|
|
3228
3086
|
/**
|
|
@@ -3281,6 +3139,8 @@ function templateParameters(template, parameters) {
|
|
|
3281
3139
|
throw new PipelineExecutionError("Parameter `{".concat(parameterName, "}` is not defined"));
|
|
3282
3140
|
}
|
|
3283
3141
|
parameterValue = valueToString(parameterValue);
|
|
3142
|
+
// Escape curly braces in parameter values to prevent prompt-injection
|
|
3143
|
+
parameterValue = parameterValue.replace(/[{}]/g, '\\$&');
|
|
3284
3144
|
if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
|
|
3285
3145
|
parameterValue = parameterValue
|
|
3286
3146
|
.split('\n')
|
|
@@ -3901,7 +3761,7 @@ function executeAttempts(options) {
|
|
|
3901
3761
|
promptTitle: task.title,
|
|
3902
3762
|
promptMessage: templateParameters(task.description || '', parameters),
|
|
3903
3763
|
defaultValue: templateParameters(preparedContent, parameters),
|
|
3904
|
-
// TODO: [🧠]
|
|
3764
|
+
// TODO: [🧠] Figure out how to define placeholder in .book.md file
|
|
3905
3765
|
placeholder: undefined,
|
|
3906
3766
|
priority: priority,
|
|
3907
3767
|
}))];
|
|
@@ -4601,7 +4461,10 @@ function executePipeline(options) {
|
|
|
4601
4461
|
finally { if (e_2) throw e_2.error; }
|
|
4602
4462
|
return [7 /*endfinally*/];
|
|
4603
4463
|
case 19:
|
|
4604
|
-
parametersToPass = inputParameters
|
|
4464
|
+
parametersToPass = Object.fromEntries(Object.entries(inputParameters).map(function (_a) {
|
|
4465
|
+
var _b = __read(_a, 2), key = _b[0], value = _b[1];
|
|
4466
|
+
return [key, valueToString(value)];
|
|
4467
|
+
}));
|
|
4605
4468
|
_g.label = 20;
|
|
4606
4469
|
case 20:
|
|
4607
4470
|
_g.trys.push([20, 25, , 28]);
|
|
@@ -4836,6 +4699,169 @@ function createPipelineExecutor(options) {
|
|
|
4836
4699
|
* TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
|
|
4837
4700
|
*/
|
|
4838
4701
|
|
|
4702
|
+
/**
|
|
4703
|
+
* Async version of Array.forEach
|
|
4704
|
+
*
|
|
4705
|
+
* @param array - Array to iterate over
|
|
4706
|
+
* @param options - Options for the function
|
|
4707
|
+
* @param callbackfunction - Function to call for each item
|
|
4708
|
+
* @public exported from `@promptbook/utils`
|
|
4709
|
+
* @deprecated [🪂] Use queues instead
|
|
4710
|
+
*/
|
|
4711
|
+
function forEachAsync(array, options, callbackfunction) {
|
|
4712
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
4713
|
+
var _a, maxParallelCount, index, runningTasks, tasks, _loop_1, _b, _c, item, e_1_1;
|
|
4714
|
+
var e_1, _d;
|
|
4715
|
+
return __generator(this, function (_e) {
|
|
4716
|
+
switch (_e.label) {
|
|
4717
|
+
case 0:
|
|
4718
|
+
_a = options.maxParallelCount, maxParallelCount = _a === void 0 ? Infinity : _a;
|
|
4719
|
+
index = 0;
|
|
4720
|
+
runningTasks = [];
|
|
4721
|
+
tasks = [];
|
|
4722
|
+
_loop_1 = function (item) {
|
|
4723
|
+
var currentIndex, task;
|
|
4724
|
+
return __generator(this, function (_f) {
|
|
4725
|
+
switch (_f.label) {
|
|
4726
|
+
case 0:
|
|
4727
|
+
currentIndex = index++;
|
|
4728
|
+
task = callbackfunction(item, currentIndex, array);
|
|
4729
|
+
tasks.push(task);
|
|
4730
|
+
runningTasks.push(task);
|
|
4731
|
+
/* not await */ Promise.resolve(task).then(function () {
|
|
4732
|
+
runningTasks = runningTasks.filter(function (t) { return t !== task; });
|
|
4733
|
+
});
|
|
4734
|
+
if (!(maxParallelCount < runningTasks.length)) return [3 /*break*/, 2];
|
|
4735
|
+
return [4 /*yield*/, Promise.race(runningTasks)];
|
|
4736
|
+
case 1:
|
|
4737
|
+
_f.sent();
|
|
4738
|
+
_f.label = 2;
|
|
4739
|
+
case 2: return [2 /*return*/];
|
|
4740
|
+
}
|
|
4741
|
+
});
|
|
4742
|
+
};
|
|
4743
|
+
_e.label = 1;
|
|
4744
|
+
case 1:
|
|
4745
|
+
_e.trys.push([1, 6, 7, 8]);
|
|
4746
|
+
_b = __values(array), _c = _b.next();
|
|
4747
|
+
_e.label = 2;
|
|
4748
|
+
case 2:
|
|
4749
|
+
if (!!_c.done) return [3 /*break*/, 5];
|
|
4750
|
+
item = _c.value;
|
|
4751
|
+
return [5 /*yield**/, _loop_1(item)];
|
|
4752
|
+
case 3:
|
|
4753
|
+
_e.sent();
|
|
4754
|
+
_e.label = 4;
|
|
4755
|
+
case 4:
|
|
4756
|
+
_c = _b.next();
|
|
4757
|
+
return [3 /*break*/, 2];
|
|
4758
|
+
case 5: return [3 /*break*/, 8];
|
|
4759
|
+
case 6:
|
|
4760
|
+
e_1_1 = _e.sent();
|
|
4761
|
+
e_1 = { error: e_1_1 };
|
|
4762
|
+
return [3 /*break*/, 8];
|
|
4763
|
+
case 7:
|
|
4764
|
+
try {
|
|
4765
|
+
if (_c && !_c.done && (_d = _b.return)) _d.call(_b);
|
|
4766
|
+
}
|
|
4767
|
+
finally { if (e_1) throw e_1.error; }
|
|
4768
|
+
return [7 /*endfinally*/];
|
|
4769
|
+
case 8: return [4 /*yield*/, Promise.all(tasks)];
|
|
4770
|
+
case 9:
|
|
4771
|
+
_e.sent();
|
|
4772
|
+
return [2 /*return*/];
|
|
4773
|
+
}
|
|
4774
|
+
});
|
|
4775
|
+
});
|
|
4776
|
+
}
|
|
4777
|
+
|
|
4778
|
+
/**
|
|
4779
|
+
* Intercepts LLM tools and counts total usage of the tools
|
|
4780
|
+
*
|
|
4781
|
+
* @param llmTools LLM tools to be intercepted with usage counting
|
|
4782
|
+
* @returns LLM tools with same functionality with added total cost counting
|
|
4783
|
+
* @public exported from `@promptbook/core`
|
|
4784
|
+
*/
|
|
4785
|
+
function countTotalUsage(llmTools) {
|
|
4786
|
+
var _this = this;
|
|
4787
|
+
var totalUsage = ZERO_USAGE;
|
|
4788
|
+
var proxyTools = {
|
|
4789
|
+
get title() {
|
|
4790
|
+
// TODO: [🧠] Maybe put here some suffix
|
|
4791
|
+
return llmTools.title;
|
|
4792
|
+
},
|
|
4793
|
+
get description() {
|
|
4794
|
+
// TODO: [🧠] Maybe put here some suffix
|
|
4795
|
+
return llmTools.description;
|
|
4796
|
+
},
|
|
4797
|
+
checkConfiguration: function () {
|
|
4798
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
4799
|
+
return __generator(this, function (_a) {
|
|
4800
|
+
return [2 /*return*/, /* not await */ llmTools.checkConfiguration()];
|
|
4801
|
+
});
|
|
4802
|
+
});
|
|
4803
|
+
},
|
|
4804
|
+
listModels: function () {
|
|
4805
|
+
return /* not await */ llmTools.listModels();
|
|
4806
|
+
},
|
|
4807
|
+
getTotalUsage: function () {
|
|
4808
|
+
// <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
|
|
4809
|
+
return totalUsage;
|
|
4810
|
+
},
|
|
4811
|
+
};
|
|
4812
|
+
if (llmTools.callChatModel !== undefined) {
|
|
4813
|
+
proxyTools.callChatModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
|
|
4814
|
+
var promptResult;
|
|
4815
|
+
return __generator(this, function (_a) {
|
|
4816
|
+
switch (_a.label) {
|
|
4817
|
+
case 0: return [4 /*yield*/, llmTools.callChatModel(prompt)];
|
|
4818
|
+
case 1:
|
|
4819
|
+
promptResult = _a.sent();
|
|
4820
|
+
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
4821
|
+
return [2 /*return*/, promptResult];
|
|
4822
|
+
}
|
|
4823
|
+
});
|
|
4824
|
+
}); };
|
|
4825
|
+
}
|
|
4826
|
+
if (llmTools.callCompletionModel !== undefined) {
|
|
4827
|
+
proxyTools.callCompletionModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
|
|
4828
|
+
var promptResult;
|
|
4829
|
+
return __generator(this, function (_a) {
|
|
4830
|
+
switch (_a.label) {
|
|
4831
|
+
case 0: return [4 /*yield*/, llmTools.callCompletionModel(prompt)];
|
|
4832
|
+
case 1:
|
|
4833
|
+
promptResult = _a.sent();
|
|
4834
|
+
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
4835
|
+
return [2 /*return*/, promptResult];
|
|
4836
|
+
}
|
|
4837
|
+
});
|
|
4838
|
+
}); };
|
|
4839
|
+
}
|
|
4840
|
+
if (llmTools.callEmbeddingModel !== undefined) {
|
|
4841
|
+
proxyTools.callEmbeddingModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
|
|
4842
|
+
var promptResult;
|
|
4843
|
+
return __generator(this, function (_a) {
|
|
4844
|
+
switch (_a.label) {
|
|
4845
|
+
case 0: return [4 /*yield*/, llmTools.callEmbeddingModel(prompt)];
|
|
4846
|
+
case 1:
|
|
4847
|
+
promptResult = _a.sent();
|
|
4848
|
+
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
4849
|
+
return [2 /*return*/, promptResult];
|
|
4850
|
+
}
|
|
4851
|
+
});
|
|
4852
|
+
}); };
|
|
4853
|
+
}
|
|
4854
|
+
// <- Note: [🤖]
|
|
4855
|
+
return proxyTools;
|
|
4856
|
+
}
|
|
4857
|
+
/**
|
|
4858
|
+
* TODO: [🧠][💸] Maybe make some common abstraction `interceptLlmTools` and use here (or use javascript Proxy?)
|
|
4859
|
+
* TODO: [🧠] Is there some meaningfull way how to test this util
|
|
4860
|
+
* TODO: [🧠][🌯] Maybe a way how to hide ability to `get totalUsage`
|
|
4861
|
+
* > const [llmToolsWithUsage,getUsage] = countTotalUsage(llmTools);
|
|
4862
|
+
* TODO: [👷♂️] @@@ Manual about construction of llmTools
|
|
4863
|
+
*/
|
|
4864
|
+
|
|
4839
4865
|
/**
|
|
4840
4866
|
* Prepares the persona for the pipeline
|
|
4841
4867
|
*
|
|
@@ -4898,10 +4924,10 @@ function preparePersona(personaDescription, tools, options) {
|
|
|
4898
4924
|
});
|
|
4899
4925
|
}
|
|
4900
4926
|
/**
|
|
4901
|
-
* TODO: [🔃][main]
|
|
4902
|
-
* TODO: [🏢]
|
|
4903
|
-
* TODO: [🏢]
|
|
4904
|
-
* TODO: [🏢]
|
|
4927
|
+
* TODO: [🔃][main] If the persona was prepared with different version or different set of models, prepare it once again
|
|
4928
|
+
* TODO: [🏢] Check validity of `modelName` in pipeline
|
|
4929
|
+
* TODO: [🏢] Check validity of `systemMessage` in pipeline
|
|
4930
|
+
* TODO: [🏢] Check validity of `temperature` in pipeline
|
|
4905
4931
|
*/
|
|
4906
4932
|
|
|
4907
4933
|
/**
|
|
@@ -5335,21 +5361,44 @@ function isValidFilePath(filename) {
|
|
|
5335
5361
|
if (typeof filename !== 'string') {
|
|
5336
5362
|
return false;
|
|
5337
5363
|
}
|
|
5364
|
+
if (filename.split('\n').length > 1) {
|
|
5365
|
+
return false;
|
|
5366
|
+
}
|
|
5367
|
+
if (filename.split(' ').length >
|
|
5368
|
+
5 /* <- TODO: [🧠][🈷] Make some better non-arbitrary way how to distinct filenames from informational texts */) {
|
|
5369
|
+
return false;
|
|
5370
|
+
}
|
|
5338
5371
|
var filenameSlashes = filename.split('\\').join('/');
|
|
5339
5372
|
// Absolute Unix path: /hello.txt
|
|
5340
5373
|
if (/^(\/)/i.test(filenameSlashes)) {
|
|
5374
|
+
// console.log(filename, 'Absolute Unix path: /hello.txt');
|
|
5341
5375
|
return true;
|
|
5342
5376
|
}
|
|
5343
5377
|
// Absolute Windows path: /hello.txt
|
|
5344
5378
|
if (/^([A-Z]{1,2}:\/?)\//i.test(filenameSlashes)) {
|
|
5379
|
+
// console.log(filename, 'Absolute Windows path: /hello.txt');
|
|
5345
5380
|
return true;
|
|
5346
5381
|
}
|
|
5347
5382
|
// Relative path: ./hello.txt
|
|
5348
5383
|
if (/^(\.\.?\/)+/i.test(filenameSlashes)) {
|
|
5384
|
+
// console.log(filename, 'Relative path: ./hello.txt');
|
|
5385
|
+
return true;
|
|
5386
|
+
}
|
|
5387
|
+
// Allow paths like foo/hello
|
|
5388
|
+
if (/^[^/]+\/[^/]+/i.test(filenameSlashes)) {
|
|
5389
|
+
// console.log(filename, 'Allow paths like foo/hello');
|
|
5390
|
+
return true;
|
|
5391
|
+
}
|
|
5392
|
+
// Allow paths like hello.book
|
|
5393
|
+
if (/^[^/]+\.[^/]+$/i.test(filenameSlashes)) {
|
|
5394
|
+
// console.log(filename, 'Allow paths like hello.book');
|
|
5349
5395
|
return true;
|
|
5350
5396
|
}
|
|
5351
5397
|
return false;
|
|
5352
5398
|
}
|
|
5399
|
+
/**
|
|
5400
|
+
* TODO: [🍏] Implement for MacOs
|
|
5401
|
+
*/
|
|
5353
5402
|
|
|
5354
5403
|
/**
|
|
5355
5404
|
* The built-in `fetch' function with a lightweight error handling wrapper as default fetch function used in Promptbook scrapers
|
|
@@ -5374,6 +5423,9 @@ var scraperFetch = function (url, init) { return __awaiter(void 0, void 0, void
|
|
|
5374
5423
|
}
|
|
5375
5424
|
});
|
|
5376
5425
|
}); };
|
|
5426
|
+
/**
|
|
5427
|
+
* TODO: [🧠] Maybe rename because it is not used only for scrapers but also in `$getCompiledBook`
|
|
5428
|
+
*/
|
|
5377
5429
|
|
|
5378
5430
|
/**
|
|
5379
5431
|
* @@@
|
|
@@ -5441,7 +5493,7 @@ function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
|
|
|
5441
5493
|
},
|
|
5442
5494
|
}];
|
|
5443
5495
|
case 2:
|
|
5444
|
-
if (!
|
|
5496
|
+
if (!isValidFilePath(sourceContent)) return [3 /*break*/, 4];
|
|
5445
5497
|
if (tools.fs === undefined) {
|
|
5446
5498
|
throw new EnvironmentMismatchError('Can not import file knowledge without filesystem tools');
|
|
5447
5499
|
// <- TODO: [🧠] What is the best error type here`
|
|
@@ -5456,7 +5508,7 @@ function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
|
|
|
5456
5508
|
return [4 /*yield*/, isFileExisting(filename_1, tools.fs)];
|
|
5457
5509
|
case 3:
|
|
5458
5510
|
if (!(_f.sent())) {
|
|
5459
|
-
throw new NotFoundError(spaceTrim(function (block) { return "\n Can not make source handler for file which does not exist:\n\n File:\n ".concat(block(filename_1), "\n "); }));
|
|
5511
|
+
throw new NotFoundError(spaceTrim(function (block) { return "\n Can not make source handler for file which does not exist:\n\n File:\n ".concat(block(sourceContent), "\n\n Full file path:\n ").concat(block(filename_1), "\n "); }));
|
|
5460
5512
|
}
|
|
5461
5513
|
// TODO: [🧠][😿] Test security file - file is scoped to the project (BUT maybe do this in `filesystemTools`)
|
|
5462
5514
|
return [2 /*return*/, {
|
|
@@ -5569,7 +5621,7 @@ function prepareKnowledgePieces(knowledgeSources, tools, options) {
|
|
|
5569
5621
|
partialPieces = __spreadArray([], __read(partialPiecesUnchecked), false);
|
|
5570
5622
|
return [2 /*return*/, "break"];
|
|
5571
5623
|
}
|
|
5572
|
-
console.warn(spaceTrim(function (block) { return "\n Cannot scrape knowledge from source despite the scraper `".concat(scraper.metadata.className, "` supports the mime type \"").concat(sourceHandler.mimeType, "\".\n
|
|
5624
|
+
console.warn(spaceTrim(function (block) { return "\n Cannot scrape knowledge from source despite the scraper `".concat(scraper.metadata.className, "` supports the mime type \"").concat(sourceHandler.mimeType, "\".\n\n The source:\n ").concat(block(knowledgeSource.sourceContent
|
|
5573
5625
|
.split('\n')
|
|
5574
5626
|
.map(function (line) { return "> ".concat(line); })
|
|
5575
5627
|
.join('\n')), "\n\n ").concat(block($registeredScrapersMessage(scrapers)), "\n\n\n "); }));
|
|
@@ -5607,7 +5659,7 @@ function prepareKnowledgePieces(knowledgeSources, tools, options) {
|
|
|
5607
5659
|
return [7 /*endfinally*/];
|
|
5608
5660
|
case 9:
|
|
5609
5661
|
if (partialPieces === null) {
|
|
5610
|
-
throw new KnowledgeScrapeError(spaceTrim(function (block) { return "\n Cannot scrape knowledge\n
|
|
5662
|
+
throw new KnowledgeScrapeError(spaceTrim(function (block) { return "\n Cannot scrape knowledge\n\n The source:\n > ".concat(block(knowledgeSource.sourceContent
|
|
5611
5663
|
.split('\n')
|
|
5612
5664
|
.map(function (line) { return "> ".concat(line); })
|
|
5613
5665
|
.join('\n')), "\n\n No scraper found for the mime type \"").concat(sourceHandler.mimeType, "\"\n\n ").concat(block($registeredScrapersMessage(scrapers)), "\n\n\n "); }));
|
|
@@ -5698,7 +5750,7 @@ function prepareTasks(pipeline, tools, options) {
|
|
|
5698
5750
|
* TODO: [😂] Adding knowledge should be convert to async high-level abstractions, simmilar thing with expectations to sync high-level abstractions
|
|
5699
5751
|
* TODO: [🧠] Add context to each task (if missing)
|
|
5700
5752
|
* TODO: [🧠] What is better name `prepareTask` or `prepareTaskAndParameters`
|
|
5701
|
-
* TODO: [♨][main]
|
|
5753
|
+
* TODO: [♨][main] !!3 Prepare index the examples and maybe tasks
|
|
5702
5754
|
* TODO: Write tests for `preparePipeline`
|
|
5703
5755
|
* TODO: [🏏] Leverage the batch API and build queues @see https://platform.openai.com/docs/guides/batch
|
|
5704
5756
|
* TODO: [🧊] In future one preparation can take data from previous preparation and save tokens and time
|
|
@@ -5706,7 +5758,9 @@ function prepareTasks(pipeline, tools, options) {
|
|
|
5706
5758
|
*/
|
|
5707
5759
|
|
|
5708
5760
|
/**
|
|
5709
|
-
* Prepare pipeline
|
|
5761
|
+
* Prepare pipeline locally
|
|
5762
|
+
*
|
|
5763
|
+
* @see https://github.com/webgptorg/promptbook/discussions/196
|
|
5710
5764
|
*
|
|
5711
5765
|
* Note: This function does not validate logic of the pipeline
|
|
5712
5766
|
* Note: This function acts as part of compilation process
|
|
@@ -5720,16 +5774,17 @@ function preparePipeline(pipeline, tools, options) {
|
|
|
5720
5774
|
<- TODO: [🧠][🪑] `promptbookVersion` */
|
|
5721
5775
|
knowledgeSources /*
|
|
5722
5776
|
<- TODO: [🧊] `knowledgePieces` */, personas /*
|
|
5723
|
-
<- TODO: [🧊] `preparations` */, _llms, llmTools, llmToolsWithUsage, currentPreparation, preparations, preparedPersonas, knowledgeSourcesPrepared, partialknowledgePiecesPrepared, knowledgePiecesPrepared, tasksPrepared /* TODO: parameters: parametersPrepared*/;
|
|
5777
|
+
<- TODO: [🧊] `preparations` */, sources, _llms, llmTools, llmToolsWithUsage, currentPreparation, preparations, title, collection, prepareTitleExecutor, _c, result, outputParameters, titleRaw, preparedPersonas, knowledgeSourcesPrepared, partialknowledgePiecesPrepared, knowledgePiecesPrepared, tasksPrepared /* TODO: parameters: parametersPrepared*/;
|
|
5778
|
+
var _d;
|
|
5724
5779
|
var _this = this;
|
|
5725
|
-
return __generator(this, function (
|
|
5726
|
-
switch (
|
|
5780
|
+
return __generator(this, function (_e) {
|
|
5781
|
+
switch (_e.label) {
|
|
5727
5782
|
case 0:
|
|
5728
5783
|
if (isPipelinePrepared(pipeline)) {
|
|
5729
5784
|
return [2 /*return*/, pipeline];
|
|
5730
5785
|
}
|
|
5731
5786
|
rootDirname = options.rootDirname, _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? DEFAULT_MAX_PARALLEL_COUNT : _a, _b = options.isVerbose, isVerbose = _b === void 0 ? DEFAULT_IS_VERBOSE : _b;
|
|
5732
|
-
parameters = pipeline.parameters, tasks = pipeline.tasks, knowledgeSources = pipeline.knowledgeSources, personas = pipeline.personas;
|
|
5787
|
+
parameters = pipeline.parameters, tasks = pipeline.tasks, knowledgeSources = pipeline.knowledgeSources, personas = pipeline.personas, sources = pipeline.sources;
|
|
5733
5788
|
if (tools === undefined || tools.llm === undefined) {
|
|
5734
5789
|
throw new MissingToolsError('LLM tools are required for preparing the pipeline');
|
|
5735
5790
|
}
|
|
@@ -5747,6 +5802,33 @@ function preparePipeline(pipeline, tools, options) {
|
|
|
5747
5802
|
// <- TODO: [🧊]
|
|
5748
5803
|
currentPreparation,
|
|
5749
5804
|
];
|
|
5805
|
+
title = pipeline.title;
|
|
5806
|
+
if (!(title === undefined || title === '' || title === DEFAULT_BOOK_TITLE)) return [3 /*break*/, 3];
|
|
5807
|
+
collection = createCollectionFromJson.apply(void 0, __spreadArray([], __read(PipelineCollection), false));
|
|
5808
|
+
_c = createPipelineExecutor;
|
|
5809
|
+
_d = {};
|
|
5810
|
+
return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-title.book.md')];
|
|
5811
|
+
case 1:
|
|
5812
|
+
prepareTitleExecutor = _c.apply(void 0, [(_d.pipeline = _e.sent(),
|
|
5813
|
+
_d.tools = tools,
|
|
5814
|
+
_d)]);
|
|
5815
|
+
return [4 /*yield*/, prepareTitleExecutor({
|
|
5816
|
+
book: sources.map(function (_a) {
|
|
5817
|
+
var content = _a.content;
|
|
5818
|
+
return content;
|
|
5819
|
+
}).join('\n\n'),
|
|
5820
|
+
})];
|
|
5821
|
+
case 2:
|
|
5822
|
+
result = _e.sent();
|
|
5823
|
+
assertsExecutionSuccessful(result);
|
|
5824
|
+
outputParameters = result.outputParameters;
|
|
5825
|
+
titleRaw = outputParameters.title;
|
|
5826
|
+
if (isVerbose) {
|
|
5827
|
+
console.info("The title is \"".concat(titleRaw, "\""));
|
|
5828
|
+
}
|
|
5829
|
+
title = titleRaw || DEFAULT_BOOK_TITLE;
|
|
5830
|
+
_e.label = 3;
|
|
5831
|
+
case 3:
|
|
5750
5832
|
preparedPersonas = new Array(personas.length);
|
|
5751
5833
|
return [4 /*yield*/, forEachAsync(personas, { maxParallelCount: maxParallelCount /* <- TODO: [🪂] When there are subtasks, this maximul limit can be broken */ }, function (persona, index) { return __awaiter(_this, void 0, void 0, function () {
|
|
5752
5834
|
var modelRequirements, preparedPersona;
|
|
@@ -5765,12 +5847,12 @@ function preparePipeline(pipeline, tools, options) {
|
|
|
5765
5847
|
}
|
|
5766
5848
|
});
|
|
5767
5849
|
}); })];
|
|
5768
|
-
case
|
|
5769
|
-
|
|
5850
|
+
case 4:
|
|
5851
|
+
_e.sent();
|
|
5770
5852
|
knowledgeSourcesPrepared = knowledgeSources.map(function (source) { return (__assign(__assign({}, source), { preparationIds: [/* TODO: [🧊] -> */ currentPreparation.id] })); });
|
|
5771
5853
|
return [4 /*yield*/, prepareKnowledgePieces(knowledgeSources /* <- TODO: [🧊] {knowledgeSources, knowledgePieces} */, __assign(__assign({}, tools), { llm: llmToolsWithUsage }), __assign(__assign({}, options), { rootDirname: rootDirname, maxParallelCount: maxParallelCount /* <- TODO: [🪂] */, isVerbose: isVerbose }))];
|
|
5772
|
-
case
|
|
5773
|
-
partialknowledgePiecesPrepared =
|
|
5854
|
+
case 5:
|
|
5855
|
+
partialknowledgePiecesPrepared = _e.sent();
|
|
5774
5856
|
knowledgePiecesPrepared = partialknowledgePiecesPrepared.map(function (piece) { return (__assign(__assign({}, piece), { preparationIds: [/* TODO: [🧊] -> */ currentPreparation.id] })); });
|
|
5775
5857
|
return [4 /*yield*/, prepareTasks({
|
|
5776
5858
|
parameters: parameters,
|
|
@@ -5781,8 +5863,8 @@ function preparePipeline(pipeline, tools, options) {
|
|
|
5781
5863
|
maxParallelCount: maxParallelCount /* <- TODO: [🪂] */,
|
|
5782
5864
|
isVerbose: isVerbose,
|
|
5783
5865
|
})];
|
|
5784
|
-
case
|
|
5785
|
-
tasksPrepared = (
|
|
5866
|
+
case 6:
|
|
5867
|
+
tasksPrepared = (_e.sent()).tasksPrepared;
|
|
5786
5868
|
// ----- /Tasks preparation -----
|
|
5787
5869
|
// TODO: [😂] Use here all `AsyncHighLevelAbstraction`
|
|
5788
5870
|
// Note: Count total usage
|
|
@@ -5793,7 +5875,7 @@ function preparePipeline(pipeline, tools, options) {
|
|
|
5793
5875
|
order: ORDER_OF_PIPELINE_JSON,
|
|
5794
5876
|
value: __assign(__assign({}, pipeline), {
|
|
5795
5877
|
// <- TODO: Probbably deeply clone the pipeline because `$exportJson` freezes the subobjects
|
|
5796
|
-
knowledgeSources: knowledgeSourcesPrepared, knowledgePieces: knowledgePiecesPrepared, tasks: __spreadArray([], __read(tasksPrepared), false),
|
|
5878
|
+
title: title, knowledgeSources: knowledgeSourcesPrepared, knowledgePieces: knowledgePiecesPrepared, tasks: __spreadArray([], __read(tasksPrepared), false),
|
|
5797
5879
|
// <- TODO: [🪓] Here should be no need for spreading new array, just ` tasks: tasksPrepared`
|
|
5798
5880
|
personas: preparedPersonas, preparations: __spreadArray([], __read(preparations), false) }),
|
|
5799
5881
|
})];
|
|
@@ -5802,7 +5884,7 @@ function preparePipeline(pipeline, tools, options) {
|
|
|
5802
5884
|
});
|
|
5803
5885
|
}
|
|
5804
5886
|
/**
|
|
5805
|
-
* TODO: Write tests for `preparePipeline`
|
|
5887
|
+
* TODO: Write tests for `preparePipeline` and `preparePipelineOnRemoteServer`
|
|
5806
5888
|
* TODO: [🏏] Leverage the batch API and build queues @see https://platform.openai.com/docs/guides/batch
|
|
5807
5889
|
* TODO: [🧊] In future one preparation can take data from previous preparation and save tokens and time
|
|
5808
5890
|
* TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
|
|
@@ -5888,7 +5970,7 @@ var knowledgeCommandParser = {
|
|
|
5888
5970
|
if (sourceContent === '') {
|
|
5889
5971
|
throw new ParseError("Source is not defined");
|
|
5890
5972
|
}
|
|
5891
|
-
// TODO: [main]
|
|
5973
|
+
// TODO: [main] !!4 Following checks should be applied every link in the `sourceContent`
|
|
5892
5974
|
if (sourceContent.startsWith('http://')) {
|
|
5893
5975
|
throw new ParseError("Source is not secure");
|
|
5894
5976
|
}
|
|
@@ -6060,7 +6142,7 @@ var sectionCommandParser = {
|
|
|
6060
6142
|
expectResultingParameterName();
|
|
6061
6143
|
var parameter = $pipelineJson.parameters.find(function (param) { return param.name === $taskJson.resultingParameterName; });
|
|
6062
6144
|
if (parameter === undefined) {
|
|
6063
|
-
// TODO:
|
|
6145
|
+
// TODO: !!6 Change to logic error for higher level abstraction of chatbot to work
|
|
6064
6146
|
throw new ParseError("Parameter `{".concat($taskJson.resultingParameterName, "}` is not defined so can not define example value of it"));
|
|
6065
6147
|
}
|
|
6066
6148
|
parameter.exampleValues = parameter.exampleValues || [];
|
|
@@ -6071,7 +6153,7 @@ var sectionCommandParser = {
|
|
|
6071
6153
|
if (command.taskType === 'KNOWLEDGE') {
|
|
6072
6154
|
knowledgeCommandParser.$applyToPipelineJson({
|
|
6073
6155
|
type: 'KNOWLEDGE',
|
|
6074
|
-
sourceContent: $taskJson.content, // <- TODO: [🐝][main]
|
|
6156
|
+
sourceContent: $taskJson.content, // <- TODO: [🐝][main] !!3 Work with KNOWLEDGE which not referring to the source file or website, but its content itself
|
|
6075
6157
|
}, $pipelineJson);
|
|
6076
6158
|
$taskJson.isTask = false;
|
|
6077
6159
|
return;
|
|
@@ -6966,20 +7048,24 @@ var ChatbotFormfactorDefinition = {
|
|
|
6966
7048
|
*/
|
|
6967
7049
|
var GeneratorFormfactorDefinition = {
|
|
6968
7050
|
name: 'GENERATOR',
|
|
6969
|
-
description: "
|
|
7051
|
+
description: "Generates any kind (in HTML with possible scripts and css format) of content from input message",
|
|
6970
7052
|
documentationUrl: "https://github.com/webgptorg/promptbook/discussions/184",
|
|
6971
7053
|
pipelineInterface: {
|
|
6972
7054
|
inputParameters: [
|
|
6973
|
-
/* @@@ */
|
|
6974
7055
|
{
|
|
6975
|
-
name: '
|
|
6976
|
-
description:
|
|
7056
|
+
name: 'inputMessage',
|
|
7057
|
+
description: "Input message to be image made from",
|
|
6977
7058
|
isInput: true,
|
|
6978
7059
|
isOutput: false,
|
|
6979
7060
|
},
|
|
6980
7061
|
],
|
|
6981
7062
|
outputParameters: [
|
|
6982
|
-
|
|
7063
|
+
{
|
|
7064
|
+
name: 'result',
|
|
7065
|
+
description: "Result in HTML to be shown to user",
|
|
7066
|
+
isInput: false,
|
|
7067
|
+
isOutput: true,
|
|
7068
|
+
},
|
|
6983
7069
|
],
|
|
6984
7070
|
},
|
|
6985
7071
|
};
|
|
@@ -7011,6 +7097,35 @@ var GenericFormfactorDefinition = {
|
|
|
7011
7097
|
pipelineInterface: GENERIC_PIPELINE_INTERFACE,
|
|
7012
7098
|
};
|
|
7013
7099
|
|
|
7100
|
+
/**
|
|
7101
|
+
* Image generator is form of app that generates image from input message
|
|
7102
|
+
*
|
|
7103
|
+
* @public exported from `@promptbook/core`
|
|
7104
|
+
*/
|
|
7105
|
+
var ImageGeneratorFormfactorDefinition = {
|
|
7106
|
+
name: 'IMAGE_GENERATOR',
|
|
7107
|
+
description: "Generates prompt for image generation from input message",
|
|
7108
|
+
documentationUrl: "https://github.com/webgptorg/promptbook/discussions/184",
|
|
7109
|
+
pipelineInterface: {
|
|
7110
|
+
inputParameters: [
|
|
7111
|
+
{
|
|
7112
|
+
name: 'inputMessage',
|
|
7113
|
+
description: "Input message to be image made from",
|
|
7114
|
+
isInput: true,
|
|
7115
|
+
isOutput: false,
|
|
7116
|
+
},
|
|
7117
|
+
],
|
|
7118
|
+
outputParameters: [
|
|
7119
|
+
{
|
|
7120
|
+
name: 'prompt',
|
|
7121
|
+
description: "Prompt to be used for image generation",
|
|
7122
|
+
isInput: false,
|
|
7123
|
+
isOutput: true,
|
|
7124
|
+
},
|
|
7125
|
+
],
|
|
7126
|
+
},
|
|
7127
|
+
};
|
|
7128
|
+
|
|
7014
7129
|
/**
|
|
7015
7130
|
* Matcher is form of app that @@@
|
|
7016
7131
|
*
|
|
@@ -7109,6 +7224,7 @@ var FORMFACTOR_DEFINITIONS = [
|
|
|
7109
7224
|
SheetsFormfactorDefinition,
|
|
7110
7225
|
MatcherFormfactorDefinition,
|
|
7111
7226
|
GeneratorFormfactorDefinition,
|
|
7227
|
+
ImageGeneratorFormfactorDefinition,
|
|
7112
7228
|
];
|
|
7113
7229
|
/**
|
|
7114
7230
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -7495,7 +7611,7 @@ var parameterCommandParser = {
|
|
|
7495
7611
|
* Note: `$` is used to indicate that this function mutates given `pipelineJson`
|
|
7496
7612
|
*/
|
|
7497
7613
|
$applyToPipelineJson: function (command, $pipelineJson) {
|
|
7498
|
-
// Note: [🍣] Do nothing, its application is implemented separately in `
|
|
7614
|
+
// Note: [🍣] Do nothing, its application is implemented separately in `parsePipeline`
|
|
7499
7615
|
},
|
|
7500
7616
|
/**
|
|
7501
7617
|
* Apply the PARAMETER command to the `pipelineJson`
|
|
@@ -7503,7 +7619,7 @@ var parameterCommandParser = {
|
|
|
7503
7619
|
* Note: `$` is used to indicate that this function mutates given `taskJson`
|
|
7504
7620
|
*/
|
|
7505
7621
|
$applyToTaskJson: function (command, $taskJson, $pipelineJson) {
|
|
7506
|
-
// Note: [🍣] Do nothing, its application is implemented separately in `
|
|
7622
|
+
// Note: [🍣] Do nothing, its application is implemented separately in `parsePipeline`
|
|
7507
7623
|
},
|
|
7508
7624
|
/**
|
|
7509
7625
|
* Converts the PARAMETER command back to string
|
|
@@ -7998,7 +8114,7 @@ var COMMANDS = [
|
|
|
7998
8114
|
instrumentCommandParser,
|
|
7999
8115
|
personaCommandParser,
|
|
8000
8116
|
foreachCommandParser,
|
|
8001
|
-
boilerplateCommandParser, // <- TODO:
|
|
8117
|
+
boilerplateCommandParser, // <- TODO: Only in development, remove in production
|
|
8002
8118
|
// <- Note: [♓️][💩] This is the order of the commands in the pipeline, BUT its not used in parsing and before usage maybe it should be done better
|
|
8003
8119
|
];
|
|
8004
8120
|
/**
|
|
@@ -8422,7 +8538,7 @@ var QuickChatbotHla = {
|
|
|
8422
8538
|
isOutput: true,
|
|
8423
8539
|
exampleValues: ['Hello, I am a Pavol`s virtual avatar. How can I help you?'],
|
|
8424
8540
|
});
|
|
8425
|
-
// TODO:
|
|
8541
|
+
// TODO: Use spaceTrim in multiline strings
|
|
8426
8542
|
$pipelineJson.tasks.push({
|
|
8427
8543
|
taskType: 'PROMPT_TASK',
|
|
8428
8544
|
name: 'create-an-answer',
|
|
@@ -8430,8 +8546,11 @@ var QuickChatbotHla = {
|
|
|
8430
8546
|
content: 'Write a response to the user message:\n\n**Question from user**\n\n> {userMessage}\n\n**Previous conversation**\n\n> {previousConversationSummary}',
|
|
8431
8547
|
resultingParameterName: 'chatbotResponse',
|
|
8432
8548
|
personaName: personaName,
|
|
8433
|
-
dependentParameterNames: [
|
|
8434
|
-
|
|
8549
|
+
dependentParameterNames: [
|
|
8550
|
+
'userMessage',
|
|
8551
|
+
'previousConversationSummary' /* TODO: [🧠][📛], 'knowledge'*/,
|
|
8552
|
+
],
|
|
8553
|
+
// TODO: [🧠][📛] preparedContent: '{content}\n\n## Knowledge\n\n{knowledge}',
|
|
8435
8554
|
}, {
|
|
8436
8555
|
taskType: 'PROMPT_TASK',
|
|
8437
8556
|
name: 'summarize-the-conversation',
|
|
@@ -8445,24 +8564,27 @@ var QuickChatbotHla = {
|
|
|
8445
8564
|
max: 10,
|
|
8446
8565
|
},
|
|
8447
8566
|
},
|
|
8448
|
-
dependentParameterNames: ['userMessage', 'chatbotResponse' /*
|
|
8449
|
-
//
|
|
8567
|
+
dependentParameterNames: ['userMessage', 'chatbotResponse' /* TODO: [🧠][📛], 'knowledge'*/],
|
|
8568
|
+
// TODO: [🧠][📛] preparedContent: '{content}\n\n## Knowledge\n\n{knowledge}',
|
|
8450
8569
|
}, {
|
|
8451
8570
|
taskType: 'SIMPLE_TASK',
|
|
8452
8571
|
name: 'title',
|
|
8453
8572
|
title: 'Title',
|
|
8454
8573
|
content: '{conversationSummary}',
|
|
8455
8574
|
resultingParameterName: 'title',
|
|
8456
|
-
dependentParameterNames: ['conversationSummary' /*
|
|
8457
|
-
//
|
|
8575
|
+
dependentParameterNames: ['conversationSummary' /* TODO: [🧠][📛], 'knowledge'*/],
|
|
8576
|
+
// TODO: [🧠][📛] preparedContent: '{content}\n\n## Knowledge\n\n{knowledge}',
|
|
8458
8577
|
});
|
|
8459
8578
|
},
|
|
8460
8579
|
};
|
|
8580
|
+
/**
|
|
8581
|
+
* TODO: [🧠][📛] Should this be here?
|
|
8582
|
+
*/
|
|
8461
8583
|
|
|
8462
8584
|
/**
|
|
8463
8585
|
* All high-level abstractions
|
|
8464
8586
|
*
|
|
8465
|
-
* @private internal index of `
|
|
8587
|
+
* @private internal index of `parsePipeline` (= used for sync) and `preparePipeline` (= used for async)
|
|
8466
8588
|
*/
|
|
8467
8589
|
var HIGH_LEVEL_ABSTRACTIONS = [
|
|
8468
8590
|
ImplicitFormfactorHla,
|
|
@@ -8596,7 +8718,7 @@ function splitMarkdownIntoSections(markdown) {
|
|
|
8596
8718
|
return;
|
|
8597
8719
|
}
|
|
8598
8720
|
if (!section.startsWith('#')) {
|
|
8599
|
-
section = "# ".concat(
|
|
8721
|
+
section = "# ".concat(DEFAULT_BOOK_TITLE, "\n\n").concat(section);
|
|
8600
8722
|
}
|
|
8601
8723
|
sections.push(section);
|
|
8602
8724
|
buffer = [];
|
|
@@ -8651,7 +8773,7 @@ function splitMarkdownIntoSections(markdown) {
|
|
|
8651
8773
|
/**
|
|
8652
8774
|
* Normalizes the markdown by flattening the structure
|
|
8653
8775
|
*
|
|
8654
|
-
* - It always have h1 - if there is no h1 in the markdown, it will be added
|
|
8776
|
+
* - It always have h1 - if there is no h1 in the markdown, it will be added `DEFAULT_BOOK_TITLE`
|
|
8655
8777
|
* - All other headings are normalized to h2
|
|
8656
8778
|
*
|
|
8657
8779
|
* @public exported from `@promptbook/markdown-utils`
|
|
@@ -8660,7 +8782,7 @@ function flattenMarkdown(markdown) {
|
|
|
8660
8782
|
var e_1, _a;
|
|
8661
8783
|
var sections = splitMarkdownIntoSections(markdown);
|
|
8662
8784
|
if (sections.length === 0) {
|
|
8663
|
-
return "# ".concat(
|
|
8785
|
+
return "# ".concat(DEFAULT_BOOK_TITLE);
|
|
8664
8786
|
}
|
|
8665
8787
|
var flattenedMarkdown = '';
|
|
8666
8788
|
var parsedSections = sections.map(parseMarkdownSection);
|
|
@@ -8671,7 +8793,7 @@ function flattenMarkdown(markdown) {
|
|
|
8671
8793
|
}
|
|
8672
8794
|
else {
|
|
8673
8795
|
parsedSections.unshift(firstSection);
|
|
8674
|
-
flattenedMarkdown += "# ".concat(
|
|
8796
|
+
flattenedMarkdown += "# ".concat(DEFAULT_BOOK_TITLE) + "\n\n"; // <- [🧠] Maybe 3 new lines?
|
|
8675
8797
|
}
|
|
8676
8798
|
try {
|
|
8677
8799
|
for (var parsedSections_1 = __values(parsedSections), parsedSections_1_1 = parsedSections_1.next(); !parsedSections_1_1.done; parsedSections_1_1 = parsedSections_1.next()) {
|
|
@@ -8698,13 +8820,13 @@ function flattenMarkdown(markdown) {
|
|
|
8698
8820
|
*/
|
|
8699
8821
|
|
|
8700
8822
|
/**
|
|
8701
|
-
* Removes
|
|
8823
|
+
* Removes Markdown (or HTML) comments
|
|
8702
8824
|
*
|
|
8703
8825
|
* @param {string} content - The string to remove comments from.
|
|
8704
8826
|
* @returns {string} The input string with all comments removed.
|
|
8705
8827
|
* @public exported from `@promptbook/markdown-utils`
|
|
8706
8828
|
*/
|
|
8707
|
-
function
|
|
8829
|
+
function removeMarkdownComments(content) {
|
|
8708
8830
|
return spaceTrim$1(content.replace(/<!--(.*?)-->/gs, ''));
|
|
8709
8831
|
}
|
|
8710
8832
|
|
|
@@ -8737,7 +8859,7 @@ function titleToName(value) {
|
|
|
8737
8859
|
*
|
|
8738
8860
|
* Note: There are 3 similar functions:
|
|
8739
8861
|
* - `compilePipeline` **(preferred)** - which propperly compiles the promptbook and use embedding for external knowledge
|
|
8740
|
-
* - `
|
|
8862
|
+
* - `parsePipeline` - use only if you need to compile promptbook synchronously and it contains NO external knowledge
|
|
8741
8863
|
* - `preparePipeline` - just one step in the compilation process
|
|
8742
8864
|
*
|
|
8743
8865
|
* Note: This function does not validate logic of the pipeline only the parsing
|
|
@@ -8748,10 +8870,10 @@ function titleToName(value) {
|
|
|
8748
8870
|
* @throws {ParseError} if the promptbook string is not valid
|
|
8749
8871
|
* @public exported from `@promptbook/core`
|
|
8750
8872
|
*/
|
|
8751
|
-
function
|
|
8873
|
+
function parsePipeline(pipelineString) {
|
|
8752
8874
|
var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e, e_6, _f;
|
|
8753
8875
|
var $pipelineJson = {
|
|
8754
|
-
title:
|
|
8876
|
+
title: DEFAULT_BOOK_TITLE,
|
|
8755
8877
|
parameters: [],
|
|
8756
8878
|
tasks: [],
|
|
8757
8879
|
knowledgeSources: [],
|
|
@@ -8762,7 +8884,7 @@ function precompilePipeline(pipelineString) {
|
|
|
8762
8884
|
{
|
|
8763
8885
|
type: 'BOOK',
|
|
8764
8886
|
path: null,
|
|
8765
|
-
// <- TODO:
|
|
8887
|
+
// <- TODO: !!6 Pass here path of the file
|
|
8766
8888
|
content: pipelineString,
|
|
8767
8889
|
},
|
|
8768
8890
|
],
|
|
@@ -8780,18 +8902,44 @@ function precompilePipeline(pipelineString) {
|
|
|
8780
8902
|
}
|
|
8781
8903
|
// =============================================================
|
|
8782
8904
|
// Note: 1️⃣ Parsing of the markdown into object
|
|
8905
|
+
// ==============
|
|
8906
|
+
// Note: 1️⃣◽1️⃣ Remove #!shebang and comments
|
|
8783
8907
|
if (pipelineString.startsWith('#!')) {
|
|
8784
8908
|
var _g = __read(pipelineString.split('\n')), shebangLine_1 = _g[0], restLines = _g.slice(1);
|
|
8785
8909
|
if (!(shebangLine_1 || '').includes('ptbk')) {
|
|
8786
8910
|
throw new ParseError(spaceTrim$1(function (block) { return "\n It seems that you try to parse a book file which has non-standard shebang line for book files:\n Shebang line must contain 'ptbk'\n\n You have:\n ".concat(block(shebangLine_1 || '(empty line)'), "\n\n It should look like this:\n #!/usr/bin/env ptbk\n\n ").concat(block(getPipelineIdentification()), "\n "); }));
|
|
8787
8911
|
}
|
|
8788
|
-
pipelineString = restLines.join('\n');
|
|
8789
|
-
}
|
|
8790
|
-
pipelineString =
|
|
8912
|
+
pipelineString = validatePipelineString(restLines.join('\n'));
|
|
8913
|
+
}
|
|
8914
|
+
pipelineString = removeMarkdownComments(pipelineString);
|
|
8915
|
+
pipelineString = spaceTrim$1(pipelineString);
|
|
8916
|
+
// <- TODO: [😧] `spaceTrim` should preserve discriminated type *(or at lease `PipelineString`)*
|
|
8917
|
+
// ==============
|
|
8918
|
+
// Note: 1️⃣◽2️⃣ Process flat pipeline
|
|
8919
|
+
var isMarkdownBeginningWithHeadline = pipelineString.startsWith('# ');
|
|
8920
|
+
var isLastLineReturnStatement = pipelineString.split('\n').pop().split('`').join('').startsWith('->');
|
|
8921
|
+
// TODO: Also (double)check
|
|
8922
|
+
// > const usedCommands
|
|
8923
|
+
// > const isBlocksUsed
|
|
8924
|
+
// > const returnStatementCount
|
|
8925
|
+
var isFlatPipeline = !isMarkdownBeginningWithHeadline && isLastLineReturnStatement;
|
|
8926
|
+
// console.log({ isMarkdownBeginningWithHeadline, isLastLineReturnStatement, isFlatPipeline });
|
|
8927
|
+
if (isFlatPipeline) {
|
|
8928
|
+
var pipelineStringLines = pipelineString.split('\n');
|
|
8929
|
+
var returnStatement_1 = pipelineStringLines.pop();
|
|
8930
|
+
var prompt_1 = spaceTrim$1(pipelineStringLines.join('\n'));
|
|
8931
|
+
pipelineString = validatePipelineString(spaceTrim$1(function (block) { return "\n # ".concat(DEFAULT_BOOK_TITLE, "\n\n ## Prompt\n\n ```\n ").concat(block(prompt_1), "\n ```\n\n ").concat(returnStatement_1, "\n "); }));
|
|
8932
|
+
// <- TODO: Maybe use book` notation
|
|
8933
|
+
// console.log(pipelineString);
|
|
8934
|
+
}
|
|
8935
|
+
// ==============
|
|
8936
|
+
// Note: 1️⃣◽3️⃣ Parse the markdown
|
|
8791
8937
|
pipelineString = flattenMarkdown(pipelineString) /* <- Note: [🥞] */;
|
|
8792
8938
|
pipelineString = pipelineString.replaceAll(/`\{(?<parameterName>[a-z0-9_]+)\}`/gi, '{$<parameterName>}');
|
|
8793
8939
|
pipelineString = pipelineString.replaceAll(/`->\s+\{(?<parameterName>[a-z0-9_]+)\}`/gi, '-> {$<parameterName>}');
|
|
8794
8940
|
var _h = __read(splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection)), pipelineHead = _h[0], pipelineSections = _h.slice(1); /* <- Note: [🥞] */
|
|
8941
|
+
// ==============
|
|
8942
|
+
// Note: 1️⃣◽4️⃣ Check markdown structure
|
|
8795
8943
|
if (pipelineHead === undefined) {
|
|
8796
8944
|
throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Pipeline head is not defined\n\n ".concat(block(getPipelineIdentification()), "\n\n This should never happen, because the pipeline already flattened\n "); }));
|
|
8797
8945
|
}
|
|
@@ -9175,14 +9323,14 @@ function precompilePipeline(pipelineString) {
|
|
|
9175
9323
|
// =============================================================
|
|
9176
9324
|
return exportJson({
|
|
9177
9325
|
name: 'pipelineJson',
|
|
9178
|
-
message: "Result of `
|
|
9326
|
+
message: "Result of `parsePipeline`",
|
|
9179
9327
|
order: ORDER_OF_PIPELINE_JSON,
|
|
9180
9328
|
value: __assign({ formfactorName: 'GENERIC' }, $pipelineJson),
|
|
9181
9329
|
});
|
|
9182
9330
|
}
|
|
9183
9331
|
/**
|
|
9184
9332
|
* TODO: [🧠] Maybe more things here can be refactored as high-level abstractions
|
|
9185
|
-
* TODO: [main]
|
|
9333
|
+
* TODO: [main] !!4 Warn if used only sync version
|
|
9186
9334
|
* TODO: [🚞] Report here line/column of error
|
|
9187
9335
|
* TODO: Use spaceTrim more effectively
|
|
9188
9336
|
* TODO: [🧠] Parameter flags - isInput, isOutput, isInternal
|
|
@@ -9195,10 +9343,7 @@ function precompilePipeline(pipelineString) {
|
|
|
9195
9343
|
/**
|
|
9196
9344
|
* Compile pipeline from string (markdown) format to JSON format
|
|
9197
9345
|
*
|
|
9198
|
-
*
|
|
9199
|
-
* - `compilePipeline` **(preferred)** - which propperly compiles the promptbook and use embedding for external knowledge
|
|
9200
|
-
* - `precompilePipeline` - use only if you need to compile promptbook synchronously and it contains NO external knowledge
|
|
9201
|
-
* - `preparePipeline` - just one step in the compilation process
|
|
9346
|
+
* @see https://github.com/webgptorg/promptbook/discussions/196
|
|
9202
9347
|
*
|
|
9203
9348
|
* Note: This function does not validate logic of the pipeline only the parsing
|
|
9204
9349
|
* Note: This function acts as compilation process
|
|
@@ -9216,7 +9361,7 @@ function compilePipeline(pipelineString, tools, options) {
|
|
|
9216
9361
|
return __generator(this, function (_a) {
|
|
9217
9362
|
switch (_a.label) {
|
|
9218
9363
|
case 0:
|
|
9219
|
-
pipelineJson =
|
|
9364
|
+
pipelineJson = parsePipeline(pipelineString);
|
|
9220
9365
|
if (!(tools !== undefined && tools.llm !== undefined)) return [3 /*break*/, 2];
|
|
9221
9366
|
return [4 /*yield*/, preparePipeline(pipelineJson, tools, options || {
|
|
9222
9367
|
rootDirname: null,
|
|
@@ -9225,7 +9370,7 @@ function compilePipeline(pipelineString, tools, options) {
|
|
|
9225
9370
|
pipelineJson = _a.sent();
|
|
9226
9371
|
_a.label = 2;
|
|
9227
9372
|
case 2:
|
|
9228
|
-
// Note: No need to use `$exportJson` because `
|
|
9373
|
+
// Note: No need to use `$exportJson` because `parsePipeline` and `preparePipeline` already do that
|
|
9229
9374
|
return [2 /*return*/, pipelineJson];
|
|
9230
9375
|
}
|
|
9231
9376
|
});
|
|
@@ -9576,6 +9721,25 @@ var $llmToolsMetadataRegister = new $Register('llm_tools_metadata');
|
|
|
9576
9721
|
* TODO: [®] DRY Register logic
|
|
9577
9722
|
*/
|
|
9578
9723
|
|
|
9724
|
+
/**
|
|
9725
|
+
* Determines if the given path is a root path.
|
|
9726
|
+
*
|
|
9727
|
+
* Note: This does not check if the file exists only if the path is valid
|
|
9728
|
+
* @public exported from `@promptbook/utils`
|
|
9729
|
+
*/
|
|
9730
|
+
function isRootPath(value) {
|
|
9731
|
+
if (value === '/') {
|
|
9732
|
+
return true;
|
|
9733
|
+
}
|
|
9734
|
+
if (/^[A-Z]:\\$/i.test(value)) {
|
|
9735
|
+
return true;
|
|
9736
|
+
}
|
|
9737
|
+
return false;
|
|
9738
|
+
}
|
|
9739
|
+
/**
|
|
9740
|
+
* TODO: [🍏] Make for MacOS paths
|
|
9741
|
+
*/
|
|
9742
|
+
|
|
9579
9743
|
/**
|
|
9580
9744
|
* @@@
|
|
9581
9745
|
*
|
|
@@ -9590,17 +9754,45 @@ var $llmToolsMetadataRegister = new $Register('llm_tools_metadata');
|
|
|
9590
9754
|
* @public exported from `@promptbook/node`
|
|
9591
9755
|
*/
|
|
9592
9756
|
function $provideLlmToolsConfigurationFromEnv() {
|
|
9593
|
-
|
|
9594
|
-
|
|
9595
|
-
|
|
9596
|
-
|
|
9597
|
-
|
|
9598
|
-
|
|
9599
|
-
|
|
9600
|
-
|
|
9601
|
-
|
|
9602
|
-
|
|
9603
|
-
|
|
9757
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
9758
|
+
var rootDirname, i, envFilename, llmToolsConfiguration;
|
|
9759
|
+
return __generator(this, function (_a) {
|
|
9760
|
+
switch (_a.label) {
|
|
9761
|
+
case 0:
|
|
9762
|
+
if (!$isRunningInNode()) {
|
|
9763
|
+
throw new EnvironmentMismatchError('Function `$provideLlmToolsFromEnv` works only in Node.js environment');
|
|
9764
|
+
}
|
|
9765
|
+
rootDirname = process.cwd();
|
|
9766
|
+
i = 0;
|
|
9767
|
+
_a.label = 1;
|
|
9768
|
+
case 1:
|
|
9769
|
+
if (!(i < LOOP_LIMIT)) return [3 /*break*/, 4];
|
|
9770
|
+
envFilename = join(rootDirname, '.env' /* <- TODO: [🕝] Make here more candidates */);
|
|
9771
|
+
return [4 /*yield*/, isFileExisting(envFilename, $provideFilesystemForNode())];
|
|
9772
|
+
case 2:
|
|
9773
|
+
// console.log({ rootDirname, envFilename });
|
|
9774
|
+
if (_a.sent()) {
|
|
9775
|
+
dotenv.config({ path: envFilename });
|
|
9776
|
+
return [3 /*break*/, 4];
|
|
9777
|
+
}
|
|
9778
|
+
if (isRootPath(rootDirname)) {
|
|
9779
|
+
return [3 /*break*/, 4];
|
|
9780
|
+
}
|
|
9781
|
+
// Note: If the directory does not exist, try the parent directory
|
|
9782
|
+
rootDirname = join(rootDirname, '..');
|
|
9783
|
+
_a.label = 3;
|
|
9784
|
+
case 3:
|
|
9785
|
+
i++;
|
|
9786
|
+
return [3 /*break*/, 1];
|
|
9787
|
+
case 4:
|
|
9788
|
+
llmToolsConfiguration = $llmToolsMetadataRegister
|
|
9789
|
+
.list()
|
|
9790
|
+
.map(function (metadata) { return metadata.createConfigurationFromEnv(process.env); })
|
|
9791
|
+
.filter(function (configuration) { return configuration !== null; });
|
|
9792
|
+
return [2 /*return*/, llmToolsConfiguration];
|
|
9793
|
+
}
|
|
9794
|
+
});
|
|
9795
|
+
});
|
|
9604
9796
|
}
|
|
9605
9797
|
/**
|
|
9606
9798
|
* TODO: [🧠][🪁] Maybe do allow to do auto-install if package not registered and not found
|
|
@@ -9823,15 +10015,28 @@ function createLlmToolsFromConfiguration(configuration, options) {
|
|
|
9823
10015
|
*/
|
|
9824
10016
|
function $provideLlmToolsFromEnv(options) {
|
|
9825
10017
|
if (options === void 0) { options = {}; }
|
|
9826
|
-
|
|
9827
|
-
|
|
9828
|
-
|
|
9829
|
-
|
|
9830
|
-
|
|
9831
|
-
|
|
9832
|
-
|
|
9833
|
-
|
|
9834
|
-
|
|
10018
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
10019
|
+
var configuration;
|
|
10020
|
+
return __generator(this, function (_a) {
|
|
10021
|
+
switch (_a.label) {
|
|
10022
|
+
case 0:
|
|
10023
|
+
if (!$isRunningInNode()) {
|
|
10024
|
+
throw new EnvironmentMismatchError('Function `$provideLlmToolsFromEnv` works only in Node.js environment');
|
|
10025
|
+
}
|
|
10026
|
+
return [4 /*yield*/, $provideLlmToolsConfigurationFromEnv()];
|
|
10027
|
+
case 1:
|
|
10028
|
+
configuration = _a.sent();
|
|
10029
|
+
if (configuration.length === 0) {
|
|
10030
|
+
if ($llmToolsMetadataRegister.list().length === 0) {
|
|
10031
|
+
throw new UnexpectedError(spaceTrim(function (block) { return "\n No LLM tools registered, this is probably a bug in the Promptbook library\n\n ".concat(block($registeredLlmToolsMessage()), "}\n "); }));
|
|
10032
|
+
}
|
|
10033
|
+
// TODO: [🥃]
|
|
10034
|
+
throw new Error(spaceTrim(function (block) { return "\n No LLM tools found in the environment\n\n ".concat(block($registeredLlmToolsMessage()), "}\n "); }));
|
|
10035
|
+
}
|
|
10036
|
+
return [2 /*return*/, createLlmToolsFromConfiguration(configuration, options)];
|
|
10037
|
+
}
|
|
10038
|
+
});
|
|
10039
|
+
});
|
|
9835
10040
|
}
|
|
9836
10041
|
/**
|
|
9837
10042
|
* TODO: @@@ write `$provideLlmToolsFromEnv` vs `$provideLlmToolsConfigurationFromEnv` vs `createLlmToolsFromConfiguration`
|
|
@@ -9900,23 +10105,31 @@ function $provideScrapersForNode(tools, options) {
|
|
|
9900
10105
|
*/
|
|
9901
10106
|
|
|
9902
10107
|
/**
|
|
9903
|
-
*
|
|
10108
|
+
* Detects if the code is running in a browser environment in main thread (Not in a web worker)
|
|
9904
10109
|
*
|
|
9905
|
-
*
|
|
10110
|
+
* Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
|
|
9906
10111
|
*
|
|
9907
|
-
*
|
|
9908
|
-
|
|
9909
|
-
|
|
9910
|
-
|
|
9911
|
-
|
|
10112
|
+
* @public exported from `@promptbook/utils`
|
|
10113
|
+
*/
|
|
10114
|
+
new Function("\n try {\n return this === window;\n } catch (e) {\n return false;\n }\n");
|
|
10115
|
+
|
|
10116
|
+
/**
|
|
10117
|
+
* Detects if the code is running in jest environment
|
|
9912
10118
|
*
|
|
9913
|
-
*
|
|
9914
|
-
*
|
|
10119
|
+
* Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
|
|
10120
|
+
*
|
|
10121
|
+
* @public exported from `@promptbook/utils`
|
|
9915
10122
|
*/
|
|
9916
|
-
|
|
9917
|
-
|
|
9918
|
-
|
|
9919
|
-
|
|
10123
|
+
new Function("\n try {\n return process.env.JEST_WORKER_ID !== undefined;\n } catch (e) {\n return false;\n }\n");
|
|
10124
|
+
|
|
10125
|
+
/**
|
|
10126
|
+
* Detects if the code is running in a web worker
|
|
10127
|
+
*
|
|
10128
|
+
* Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
|
|
10129
|
+
*
|
|
10130
|
+
* @public exported from `@promptbook/utils`
|
|
10131
|
+
*/
|
|
10132
|
+
new Function("\n try {\n if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {\n return true;\n } else {\n return false;\n }\n } catch (e) {\n return false;\n }\n");
|
|
9920
10133
|
|
|
9921
10134
|
/**
|
|
9922
10135
|
* Makes first letter of a string uppercase
|
|
@@ -9927,6 +10140,21 @@ function decapitalize(word) {
|
|
|
9927
10140
|
return word.substring(0, 1).toLowerCase() + word.substring(1);
|
|
9928
10141
|
}
|
|
9929
10142
|
|
|
10143
|
+
/**
|
|
10144
|
+
* Parses keywords from a string
|
|
10145
|
+
*
|
|
10146
|
+
* @param {string} input
|
|
10147
|
+
* @returns {Set} of keywords without diacritics in lowercase
|
|
10148
|
+
* @public exported from `@promptbook/utils`
|
|
10149
|
+
*/
|
|
10150
|
+
function parseKeywordsFromString(input) {
|
|
10151
|
+
var keywords = normalizeTo_SCREAMING_CASE(removeDiacritics(input))
|
|
10152
|
+
.toLowerCase()
|
|
10153
|
+
.split(/[^a-z0-9]+/gs)
|
|
10154
|
+
.filter(function (value) { return value; });
|
|
10155
|
+
return new Set(keywords);
|
|
10156
|
+
}
|
|
10157
|
+
|
|
9930
10158
|
/**
|
|
9931
10159
|
* @@@
|
|
9932
10160
|
*
|
|
@@ -9980,20 +10208,39 @@ function normalizeWhitespaces(sentence) {
|
|
|
9980
10208
|
return sentence.replace(/\s+/gs, ' ').trim();
|
|
9981
10209
|
}
|
|
9982
10210
|
|
|
10211
|
+
// <- TODO: Auto convert to type `import { ... } from 'type-fest';`
|
|
9983
10212
|
/**
|
|
9984
|
-
*
|
|
10213
|
+
* Tests if the value is [🚉] serializable as JSON
|
|
10214
|
+
*
|
|
10215
|
+
* - Almost all primitives are serializable BUT:
|
|
10216
|
+
* - `undefined` is not serializable
|
|
10217
|
+
* - `NaN` is not serializable
|
|
10218
|
+
* - Objects and arrays are serializable if all their properties are serializable
|
|
10219
|
+
* - Functions are not serializable
|
|
10220
|
+
* - Circular references are not serializable
|
|
10221
|
+
* - `Date` objects are not serializable
|
|
10222
|
+
* - `Map` and `Set` objects are not serializable
|
|
10223
|
+
* - `RegExp` objects are not serializable
|
|
10224
|
+
* - `Error` objects are not serializable
|
|
10225
|
+
* - `Symbol` objects are not serializable
|
|
10226
|
+
* - And much more...
|
|
10227
|
+
*
|
|
9985
10228
|
*
|
|
9986
|
-
* @param {string} input
|
|
9987
|
-
* @returns {Set} of keywords without diacritics in lowercase
|
|
9988
10229
|
* @public exported from `@promptbook/utils`
|
|
9989
10230
|
*/
|
|
9990
|
-
function
|
|
9991
|
-
|
|
9992
|
-
|
|
9993
|
-
|
|
9994
|
-
|
|
9995
|
-
|
|
10231
|
+
function isSerializableAsJson(value) {
|
|
10232
|
+
try {
|
|
10233
|
+
checkSerializableAsJson({ value: value });
|
|
10234
|
+
return true;
|
|
10235
|
+
}
|
|
10236
|
+
catch (error) {
|
|
10237
|
+
return false;
|
|
10238
|
+
}
|
|
9996
10239
|
}
|
|
10240
|
+
/**
|
|
10241
|
+
* TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
10242
|
+
* TODO: [🧠][💺] Can be done this on type-level?
|
|
10243
|
+
*/
|
|
9997
10244
|
|
|
9998
10245
|
/**
|
|
9999
10246
|
* Function trimCodeBlock will trim starting and ending code block from the string if it is present.
|
|
@@ -10101,6 +10348,25 @@ function unwrapResult(text, options) {
|
|
|
10101
10348
|
* TODO: [🧠] Should this also unwrap the (parenthesis)
|
|
10102
10349
|
*/
|
|
10103
10350
|
|
|
10351
|
+
/**
|
|
10352
|
+
* Extracts code block from markdown.
|
|
10353
|
+
*
|
|
10354
|
+
* - When there are multiple or no code blocks the function throws a `ParseError`
|
|
10355
|
+
*
|
|
10356
|
+
* Note: There are multiple simmilar function:
|
|
10357
|
+
* - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
|
|
10358
|
+
* - `extractJsonBlock` extracts exactly one valid JSON code block
|
|
10359
|
+
* - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
|
|
10360
|
+
* - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
|
|
10361
|
+
*
|
|
10362
|
+
* @public exported from `@promptbook/markdown-utils`
|
|
10363
|
+
* @throws {ParseError} if there is not exactly one code block in the markdown
|
|
10364
|
+
*/
|
|
10365
|
+
function extractBlock(markdown) {
|
|
10366
|
+
var content = extractOneBlockFromMarkdown(markdown).content;
|
|
10367
|
+
return content;
|
|
10368
|
+
}
|
|
10369
|
+
|
|
10104
10370
|
/**
|
|
10105
10371
|
* Does nothing, but preserves the function in the bundle
|
|
10106
10372
|
* Compiler is tricked into thinking the function is used
|
|
@@ -10135,36 +10401,9 @@ function preserve(func) {
|
|
|
10135
10401
|
}); })();
|
|
10136
10402
|
}
|
|
10137
10403
|
/**
|
|
10138
|
-
* TODO:
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
/**
|
|
10142
|
-
* Converts anything to string that can be used for debugging and logging
|
|
10143
|
-
*
|
|
10144
|
-
* @param value String value for logging
|
|
10145
|
-
* @private internal util
|
|
10404
|
+
* TODO: Probbably remove in favour of `keepImported`
|
|
10405
|
+
* TODO: [1] This maybe does memory leak
|
|
10146
10406
|
*/
|
|
10147
|
-
function unknownToString(value) {
|
|
10148
|
-
if (value === undefined) {
|
|
10149
|
-
return 'undefined';
|
|
10150
|
-
}
|
|
10151
|
-
else if (value === null) {
|
|
10152
|
-
return 'null';
|
|
10153
|
-
}
|
|
10154
|
-
else if (['number', 'string', 'boolean'].includes(typeof value)) {
|
|
10155
|
-
return typeof value + ' ' + value.toString();
|
|
10156
|
-
}
|
|
10157
|
-
else if (typeof value === 'object' && Array.isArray(value)) {
|
|
10158
|
-
return 'array containing [' + value.map(function (item) { return unknownToString(item); }).join(', ') + ']';
|
|
10159
|
-
}
|
|
10160
|
-
else if (typeof value === 'object') {
|
|
10161
|
-
// TODO: Maybe serialize the object
|
|
10162
|
-
return 'object';
|
|
10163
|
-
}
|
|
10164
|
-
else {
|
|
10165
|
-
return 'unknown (Search in promptbook code for [🔹])';
|
|
10166
|
-
}
|
|
10167
|
-
}
|
|
10168
10407
|
|
|
10169
10408
|
/**
|
|
10170
10409
|
* ScriptExecutionTools for JavaScript implemented via eval
|
|
@@ -10295,7 +10534,7 @@ var JavascriptEvalExecutionTools = /** @class */ (function () {
|
|
|
10295
10534
|
case 2:
|
|
10296
10535
|
result = _a.sent();
|
|
10297
10536
|
if (typeof result !== 'string') {
|
|
10298
|
-
throw new PipelineExecutionError("Script must return a string, but returned ".concat(
|
|
10537
|
+
throw new PipelineExecutionError("Script must return a string, but returned ".concat(valueToString(result)));
|
|
10299
10538
|
}
|
|
10300
10539
|
return [3 /*break*/, 4];
|
|
10301
10540
|
case 3:
|
|
@@ -10322,7 +10561,7 @@ var JavascriptEvalExecutionTools = /** @class */ (function () {
|
|
|
10322
10561
|
throw error_1;
|
|
10323
10562
|
case 4:
|
|
10324
10563
|
if (typeof result !== 'string') {
|
|
10325
|
-
throw new PipelineExecutionError("Script must return a string, but ".concat(
|
|
10564
|
+
throw new PipelineExecutionError("Script must return a string, but ".concat(valueToString(result)));
|
|
10326
10565
|
}
|
|
10327
10566
|
return [2 /*return*/, result];
|
|
10328
10567
|
}
|
|
@@ -10362,9 +10601,11 @@ function $provideExecutionToolsForNode(options) {
|
|
|
10362
10601
|
throw new EnvironmentMismatchError('Function `$getExecutionToolsForNode` works only in Node.js environment');
|
|
10363
10602
|
}
|
|
10364
10603
|
fs = $provideFilesystemForNode();
|
|
10365
|
-
|
|
10366
|
-
return [4 /*yield*/, $provideExecutablesForNode(options)];
|
|
10604
|
+
return [4 /*yield*/, $provideLlmToolsFromEnv(options)];
|
|
10367
10605
|
case 1:
|
|
10606
|
+
llm = _b.sent();
|
|
10607
|
+
return [4 /*yield*/, $provideExecutablesForNode(options)];
|
|
10608
|
+
case 2:
|
|
10368
10609
|
executables = _b.sent();
|
|
10369
10610
|
_a = {
|
|
10370
10611
|
llm: llm,
|
|
@@ -10372,7 +10613,7 @@ function $provideExecutionToolsForNode(options) {
|
|
|
10372
10613
|
executables: executables
|
|
10373
10614
|
};
|
|
10374
10615
|
return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, options)];
|
|
10375
|
-
case
|
|
10616
|
+
case 3:
|
|
10376
10617
|
tools = (_a.scrapers = _b.sent(),
|
|
10377
10618
|
_a.script = [new JavascriptExecutionTools(options)],
|
|
10378
10619
|
_a);
|
|
@@ -10595,7 +10836,7 @@ function createCollectionFromPromise(promptbookSourcesPromiseOrFactory) {
|
|
|
10595
10836
|
*/
|
|
10596
10837
|
function createCollectionFromDirectory(path, tools, options) {
|
|
10597
10838
|
return __awaiter(this, void 0, void 0, function () {
|
|
10598
|
-
var
|
|
10839
|
+
var madeLibraryFilePath, _a, _b, isRecursive, _c, isVerbose, _d, isLazyLoaded, _e, isCrashedOnError, rootUrl, collection;
|
|
10599
10840
|
var _this = this;
|
|
10600
10841
|
return __generator(this, function (_f) {
|
|
10601
10842
|
switch (_f.label) {
|
|
@@ -10610,18 +10851,18 @@ function createCollectionFromDirectory(path, tools, options) {
|
|
|
10610
10851
|
throw new EnvironmentMismatchError('Can not create collection without filesystem tools');
|
|
10611
10852
|
// <- TODO: [🧠] What is the best error type here`
|
|
10612
10853
|
}
|
|
10613
|
-
|
|
10854
|
+
madeLibraryFilePath = join(path, "".concat(DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME
|
|
10614
10855
|
// <- TODO: [🦒] Allow to override (pass different value into the function)
|
|
10615
10856
|
, ".json"));
|
|
10616
|
-
return [4 /*yield*/, isFileExisting(
|
|
10857
|
+
return [4 /*yield*/, isFileExisting(madeLibraryFilePath, tools.fs)];
|
|
10617
10858
|
case 3:
|
|
10618
10859
|
if (!(_f.sent())) ;
|
|
10619
10860
|
else {
|
|
10620
|
-
colors.green("(In future, not implemented yet) Using your compiled pipeline collection ".concat(
|
|
10621
|
-
// TODO:
|
|
10861
|
+
colors.green("(In future, not implemented yet) Using your compiled pipeline collection ".concat(madeLibraryFilePath));
|
|
10862
|
+
// TODO: Implement;
|
|
10622
10863
|
// TODO: [🌗]
|
|
10623
10864
|
}
|
|
10624
|
-
_a = options || {}, _b = _a.isRecursive, isRecursive = _b === void 0 ? true : _b, _c = _a.isVerbose, isVerbose = _c === void 0 ? DEFAULT_IS_VERBOSE : _c, _d = _a.isLazyLoaded, isLazyLoaded = _d === void 0 ? false : _d, _e = _a.isCrashedOnError, isCrashedOnError = _e === void 0 ? true : _e;
|
|
10865
|
+
_a = options || {}, _b = _a.isRecursive, isRecursive = _b === void 0 ? true : _b, _c = _a.isVerbose, isVerbose = _c === void 0 ? DEFAULT_IS_VERBOSE : _c, _d = _a.isLazyLoaded, isLazyLoaded = _d === void 0 ? false : _d, _e = _a.isCrashedOnError, isCrashedOnError = _e === void 0 ? true : _e, rootUrl = _a.rootUrl;
|
|
10625
10866
|
collection = createCollectionFromPromise(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
10626
10867
|
var fileNames, collection, _loop_1, fileNames_1, fileNames_1_1, fileName, e_1_1;
|
|
10627
10868
|
var e_1, _a;
|
|
@@ -10647,34 +10888,35 @@ function createCollectionFromDirectory(path, tools, options) {
|
|
|
10647
10888
|
});
|
|
10648
10889
|
collection = new Map();
|
|
10649
10890
|
_loop_1 = function (fileName) {
|
|
10650
|
-
var sourceFile, rootDirname, pipeline, pipelineString, _c, _d, existing, error_1, wrappedErrorMessage;
|
|
10651
|
-
return __generator(this, function (
|
|
10652
|
-
switch (
|
|
10891
|
+
var sourceFile, rootDirname, pipeline, pipelineString, _c, _d, _e, pipelineUrl, existing, error_1, wrappedErrorMessage;
|
|
10892
|
+
return __generator(this, function (_f) {
|
|
10893
|
+
switch (_f.label) {
|
|
10653
10894
|
case 0:
|
|
10654
10895
|
sourceFile = './' + fileName.split('\\').join('/');
|
|
10655
10896
|
rootDirname = dirname(sourceFile).split('\\').join('/');
|
|
10656
|
-
|
|
10897
|
+
_f.label = 1;
|
|
10657
10898
|
case 1:
|
|
10658
|
-
|
|
10899
|
+
_f.trys.push([1, 8, , 9]);
|
|
10659
10900
|
pipeline = null;
|
|
10660
10901
|
if (!fileName.endsWith('.book.md')) return [3 /*break*/, 4];
|
|
10902
|
+
_c = validatePipelineString;
|
|
10661
10903
|
return [4 /*yield*/, readFile(fileName, 'utf-8')];
|
|
10662
10904
|
case 2:
|
|
10663
|
-
pipelineString = (
|
|
10905
|
+
pipelineString = _c.apply(void 0, [_f.sent()]);
|
|
10664
10906
|
return [4 /*yield*/, compilePipeline(pipelineString, tools, {
|
|
10665
10907
|
rootDirname: rootDirname,
|
|
10666
10908
|
})];
|
|
10667
10909
|
case 3:
|
|
10668
|
-
pipeline =
|
|
10910
|
+
pipeline = _f.sent();
|
|
10669
10911
|
pipeline = __assign(__assign({}, pipeline), { sourceFile: sourceFile });
|
|
10670
10912
|
return [3 /*break*/, 7];
|
|
10671
10913
|
case 4:
|
|
10672
10914
|
if (!fileName.endsWith('.book.json')) return [3 /*break*/, 6];
|
|
10673
|
-
|
|
10915
|
+
_e = (_d = JSON).parse;
|
|
10674
10916
|
return [4 /*yield*/, readFile(fileName, 'utf-8')];
|
|
10675
10917
|
case 5:
|
|
10676
10918
|
// TODO: Handle non-valid JSON files
|
|
10677
|
-
pipeline =
|
|
10919
|
+
pipeline = _e.apply(_d, [_f.sent()]);
|
|
10678
10920
|
// TODO: [🌗]
|
|
10679
10921
|
pipeline = __assign(__assign({}, pipeline), { sourceFile: sourceFile });
|
|
10680
10922
|
return [3 /*break*/, 7];
|
|
@@ -10682,10 +10924,24 @@ function createCollectionFromDirectory(path, tools, options) {
|
|
|
10682
10924
|
if (isVerbose) {
|
|
10683
10925
|
console.info(colors.gray("Skipped file ".concat(fileName.split('\\').join('/'), " \u2013\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060\u2060 Not a book")));
|
|
10684
10926
|
}
|
|
10685
|
-
|
|
10927
|
+
_f.label = 7;
|
|
10686
10928
|
case 7:
|
|
10687
10929
|
// ---
|
|
10688
10930
|
if (pipeline !== null) {
|
|
10931
|
+
if (rootUrl !== undefined) {
|
|
10932
|
+
if (pipeline.pipelineUrl === undefined) {
|
|
10933
|
+
pipelineUrl = rootUrl + '/' + fileName.split('\\').join('/');
|
|
10934
|
+
if (isVerbose) {
|
|
10935
|
+
console.info(colors.yellow("Implicitly set pipeline URL to ".concat(pipelineUrl, " from ").concat(fileName
|
|
10936
|
+
.split('\\')
|
|
10937
|
+
.join('/'))));
|
|
10938
|
+
}
|
|
10939
|
+
pipeline = __assign(__assign({}, pipeline), { pipelineUrl: pipelineUrl });
|
|
10940
|
+
}
|
|
10941
|
+
else if (!pipeline.pipelineUrl.startsWith(rootUrl)) {
|
|
10942
|
+
throw new PipelineUrlError(spaceTrim("\n Pipeline with URL ".concat(pipeline.pipelineUrl, " is not a child of the root URL ").concat(rootUrl, " \uD83C\uDF4F\n\n File:\n ").concat(sourceFile || 'Unknown', "\n\n ")));
|
|
10943
|
+
}
|
|
10944
|
+
}
|
|
10689
10945
|
// TODO: [👠] DRY
|
|
10690
10946
|
if (pipeline.pipelineUrl === undefined) {
|
|
10691
10947
|
if (isVerbose) {
|
|
@@ -10717,17 +10973,17 @@ function createCollectionFromDirectory(path, tools, options) {
|
|
|
10717
10973
|
}
|
|
10718
10974
|
else {
|
|
10719
10975
|
existing = collection.get(pipeline.pipelineUrl);
|
|
10720
|
-
throw new PipelineUrlError(spaceTrim("\n Pipeline with URL
|
|
10976
|
+
throw new PipelineUrlError(spaceTrim("\n Pipeline with URL ".concat(pipeline.pipelineUrl, " is already in the collection \uD83C\uDF4F\n\n Conflicting files:\n ").concat(existing.sourceFile || 'Unknown', "\n ").concat(pipeline.sourceFile || 'Unknown', "\n\n Note: You have probably forgotten to run \"ptbk make\" to update the collection\n Note: Pipelines with the same URL are not allowed\n Only exepction is when the pipelines are identical\n\n ")));
|
|
10721
10977
|
}
|
|
10722
10978
|
}
|
|
10723
10979
|
}
|
|
10724
10980
|
return [3 /*break*/, 9];
|
|
10725
10981
|
case 8:
|
|
10726
|
-
error_1 =
|
|
10982
|
+
error_1 = _f.sent();
|
|
10727
10983
|
if (!(error_1 instanceof Error)) {
|
|
10728
10984
|
throw error_1;
|
|
10729
10985
|
}
|
|
10730
|
-
wrappedErrorMessage = spaceTrim(function (block) { return "\n
|
|
10986
|
+
wrappedErrorMessage = spaceTrim(function (block) { return "\n ".concat(error_1.name, " in pipeline ").concat(fileName.split('\\').join('/'), "\u2060:\n\n Original error message:\n ").concat(block(error_1.message), "\n\n Original stack trace:\n ").concat(block(error_1.stack || ''), "\n\n ---\n\n "); }) + '\n';
|
|
10731
10987
|
if (isCrashedOnError) {
|
|
10732
10988
|
throw new CollectionError(wrappedErrorMessage);
|
|
10733
10989
|
}
|
|
@@ -10783,40 +11039,6 @@ function createCollectionFromDirectory(path, tools, options) {
|
|
|
10783
11039
|
* TODO: Maybe move from `@promptbook/node` to `@promptbook/core` as we removes direct dependency on `fs`
|
|
10784
11040
|
*/
|
|
10785
11041
|
|
|
10786
|
-
// <- TODO: !!!!!!! Auto convert to type `import { ... } from 'type-fest';`
|
|
10787
|
-
/**
|
|
10788
|
-
* Tests if the value is [🚉] serializable as JSON
|
|
10789
|
-
*
|
|
10790
|
-
* - Almost all primitives are serializable BUT:
|
|
10791
|
-
* - `undefined` is not serializable
|
|
10792
|
-
* - `NaN` is not serializable
|
|
10793
|
-
* - Objects and arrays are serializable if all their properties are serializable
|
|
10794
|
-
* - Functions are not serializable
|
|
10795
|
-
* - Circular references are not serializable
|
|
10796
|
-
* - `Date` objects are not serializable
|
|
10797
|
-
* - `Map` and `Set` objects are not serializable
|
|
10798
|
-
* - `RegExp` objects are not serializable
|
|
10799
|
-
* - `Error` objects are not serializable
|
|
10800
|
-
* - `Symbol` objects are not serializable
|
|
10801
|
-
* - And much more...
|
|
10802
|
-
*
|
|
10803
|
-
*
|
|
10804
|
-
* @public exported from `@promptbook/utils`
|
|
10805
|
-
*/
|
|
10806
|
-
function isSerializableAsJson(value) {
|
|
10807
|
-
try {
|
|
10808
|
-
checkSerializableAsJson({ value: value });
|
|
10809
|
-
return true;
|
|
10810
|
-
}
|
|
10811
|
-
catch (error) {
|
|
10812
|
-
return false;
|
|
10813
|
-
}
|
|
10814
|
-
}
|
|
10815
|
-
/**
|
|
10816
|
-
* TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
|
|
10817
|
-
* TODO: [🧠][💺] Can be done this on type-level?
|
|
10818
|
-
*/
|
|
10819
|
-
|
|
10820
11042
|
/**
|
|
10821
11043
|
* Stringify the PipelineJson with proper formatting
|
|
10822
11044
|
*
|
|
@@ -11166,45 +11388,5 @@ function $execCommands(_a) {
|
|
|
11166
11388
|
* Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
|
|
11167
11389
|
*/
|
|
11168
11390
|
|
|
11169
|
-
|
|
11170
|
-
* @@@
|
|
11171
|
-
*
|
|
11172
|
-
* @public exported from `@promptbook/node`
|
|
11173
|
-
*/
|
|
11174
|
-
var wizzard = {
|
|
11175
|
-
/**
|
|
11176
|
-
* @@@!!!!!!
|
|
11177
|
-
*/
|
|
11178
|
-
run: function (book, inputParameters, onProgress) {
|
|
11179
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
11180
|
-
var tools, collection, pipeline, pipelineExecutor, result;
|
|
11181
|
-
return __generator(this, function (_a) {
|
|
11182
|
-
switch (_a.label) {
|
|
11183
|
-
case 0: return [4 /*yield*/, $provideExecutionToolsForNode()];
|
|
11184
|
-
case 1:
|
|
11185
|
-
tools = _a.sent();
|
|
11186
|
-
return [4 /*yield*/, createCollectionFromDirectory('./books', tools)];
|
|
11187
|
-
case 2:
|
|
11188
|
-
collection = _a.sent();
|
|
11189
|
-
return [4 /*yield*/, collection.getPipelineByUrl(book)];
|
|
11190
|
-
case 3:
|
|
11191
|
-
pipeline = _a.sent();
|
|
11192
|
-
pipelineExecutor = createPipelineExecutor({ pipeline: pipeline, tools: tools });
|
|
11193
|
-
return [4 /*yield*/, pipelineExecutor(inputParameters, onProgress)];
|
|
11194
|
-
case 4:
|
|
11195
|
-
result = _a.sent();
|
|
11196
|
-
// ▶ Fail if the execution was not successful
|
|
11197
|
-
assertsExecutionSuccessful(result);
|
|
11198
|
-
// ▶ Return the result
|
|
11199
|
-
return [2 /*return*/, result];
|
|
11200
|
-
}
|
|
11201
|
-
});
|
|
11202
|
-
});
|
|
11203
|
-
},
|
|
11204
|
-
};
|
|
11205
|
-
/**
|
|
11206
|
-
* TODO: !!!!!! Add to readmes - one markdown here imported in all packages
|
|
11207
|
-
*/
|
|
11208
|
-
|
|
11209
|
-
export { $execCommand, $execCommands, $provideExecutablesForNode, $provideExecutionToolsForNode, $provideFilesystemForNode, $provideLlmToolsConfigurationFromEnv, $provideLlmToolsFromEnv, $provideScrapersForNode, BOOK_LANGUAGE_VERSION, FileCacheStorage, PROMPTBOOK_ENGINE_VERSION, createCollectionFromDirectory, wizzard };
|
|
11391
|
+
export { $execCommand, $execCommands, $provideExecutablesForNode, $provideExecutionToolsForNode, $provideFilesystemForNode, $provideLlmToolsConfigurationFromEnv, $provideLlmToolsFromEnv, $provideScrapersForNode, BOOK_LANGUAGE_VERSION, FileCacheStorage, PROMPTBOOK_ENGINE_VERSION, createCollectionFromDirectory };
|
|
11210
11392
|
//# sourceMappingURL=index.es.js.map
|