@promptbook/node 0.81.0-8 → 0.81.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 -8
- package/esm/index.es.js +1947 -1765
- 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/templates.index.d.ts +2 -2
- package/esm/typings/src/_packages/types.index.d.ts +4 -0
- 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/{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/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/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 +2 -0
- package/esm/typings/src/prepare/prepareTasks.d.ts +1 -1
- 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 +1946 -1765
- 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/utils/markdown/{removeContentComments.test.d.ts → removeMarkdownComments.test.d.ts} +0 -0
package/umd/index.umd.js
CHANGED
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
* @generated
|
|
46
46
|
* @see https://github.com/webgptorg/promptbook
|
|
47
47
|
*/
|
|
48
|
-
var PROMPTBOOK_ENGINE_VERSION = '0.81.0-
|
|
48
|
+
var PROMPTBOOK_ENGINE_VERSION = '0.81.0-24';
|
|
49
49
|
/**
|
|
50
50
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
51
51
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -215,7 +215,7 @@
|
|
|
215
215
|
*
|
|
216
216
|
* @public exported from `@promptbook/core`
|
|
217
217
|
*/
|
|
218
|
-
var
|
|
218
|
+
var DEFAULT_BOOK_TITLE = "\u2728 Untitled Book";
|
|
219
219
|
// <- TODO: [🧠] Better system for generator warnings - not always "code" and "by `@promptbook/cli`"
|
|
220
220
|
/**
|
|
221
221
|
* The maximum number of iterations for a loops
|
|
@@ -326,1412 +326,834 @@
|
|
|
326
326
|
* TODO: [🧠][🧜♂️] Maybe join remoteUrl and path into single value
|
|
327
327
|
*/
|
|
328
328
|
|
|
329
|
-
/**
|
|
330
|
-
* Orders JSON object by keys
|
|
331
|
-
*
|
|
332
|
-
* @returns The same type of object as the input re-ordered
|
|
333
|
-
* @public exported from `@promptbook/utils`
|
|
334
|
-
*/
|
|
335
|
-
function orderJson(options) {
|
|
336
|
-
var value = options.value, order = options.order;
|
|
337
|
-
var orderedValue = __assign(__assign({}, (order === undefined ? {} : Object.fromEntries(order.map(function (key) { return [key, undefined]; })))), value);
|
|
338
|
-
return orderedValue;
|
|
339
|
-
}
|
|
329
|
+
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- 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- 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 workflow:\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\n- Title starts with emoticon\n- Title should not mention the input and output of the workflow but the main purpose of the workflow\n _For example, not \"✍ Convert Knowledge-piece to title\" but \"✍ Title\"_\n\n## The workflow\n\n> {book}",resultingParameterName:"title",expectations:{words:{min:1,max:8},lines:{min:1,max:1}},dependentParameterNames:["book"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-title.book.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 workflow:\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\n- Title starts with emoticon\n- Title should not mention the input and output of the workflow but the main purpose of the workflow\n _For example, not \"✍ Convert Knowledge-piece to title\" but \"✍ Title\"_\n\n## The workflow\n\n> {book}\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-title.book.md"}];
|
|
340
330
|
|
|
341
331
|
/**
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
* Note: `$` is used to indicate that this function is not a pure function - it mutates given object
|
|
345
|
-
* Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
|
|
332
|
+
* Function isValidJsonString will tell you if the string is valid JSON or not
|
|
346
333
|
*
|
|
347
|
-
* @returns The same object as the input, but deeply frozen
|
|
348
334
|
* @public exported from `@promptbook/utils`
|
|
349
335
|
*/
|
|
350
|
-
function
|
|
351
|
-
var e_1, _a;
|
|
352
|
-
if (Array.isArray(objectValue)) {
|
|
353
|
-
return Object.freeze(objectValue.map(function (item) { return $deepFreeze(item); }));
|
|
354
|
-
}
|
|
355
|
-
var propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
336
|
+
function isValidJsonString(value /* <- [👨⚖️] */) {
|
|
356
337
|
try {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
var value = objectValue[propertyName];
|
|
360
|
-
if (value && typeof value === 'object') {
|
|
361
|
-
$deepFreeze(value);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
338
|
+
JSON.parse(value);
|
|
339
|
+
return true;
|
|
364
340
|
}
|
|
365
|
-
catch (
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
if (propertyNames_1_1 && !propertyNames_1_1.done && (_a = propertyNames_1.return)) _a.call(propertyNames_1);
|
|
341
|
+
catch (error) {
|
|
342
|
+
if (!(error instanceof Error)) {
|
|
343
|
+
throw error;
|
|
369
344
|
}
|
|
370
|
-
|
|
345
|
+
if (error.message.includes('Unexpected token')) {
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
return false;
|
|
371
349
|
}
|
|
372
|
-
Object.freeze(objectValue);
|
|
373
|
-
return objectValue;
|
|
374
|
-
}
|
|
375
|
-
/**
|
|
376
|
-
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
377
|
-
*/
|
|
378
|
-
|
|
379
|
-
/**
|
|
380
|
-
* Make error report URL for the given error
|
|
381
|
-
*
|
|
382
|
-
* @private !!!!!!
|
|
383
|
-
*/
|
|
384
|
-
function getErrorReportUrl(error) {
|
|
385
|
-
var report = {
|
|
386
|
-
title: "\uD83D\uDC1C Error report from ".concat(NAME),
|
|
387
|
-
body: spaceTrim__default["default"](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 "); }),
|
|
388
|
-
};
|
|
389
|
-
var reportUrl = new URL("https://github.com/webgptorg/promptbook/issues/new");
|
|
390
|
-
reportUrl.searchParams.set('labels', 'bug');
|
|
391
|
-
reportUrl.searchParams.set('assignees', ADMIN_GITHUB_NAME);
|
|
392
|
-
reportUrl.searchParams.set('title', report.title);
|
|
393
|
-
reportUrl.searchParams.set('body', report.body);
|
|
394
|
-
return reportUrl;
|
|
395
350
|
}
|
|
396
351
|
|
|
397
352
|
/**
|
|
398
|
-
* This error
|
|
353
|
+
* This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
|
|
399
354
|
*
|
|
400
355
|
* @public exported from `@promptbook/core`
|
|
401
356
|
*/
|
|
402
|
-
var
|
|
403
|
-
__extends(
|
|
404
|
-
function
|
|
405
|
-
var _this = _super.call(this,
|
|
406
|
-
_this.name = '
|
|
407
|
-
Object.setPrototypeOf(_this,
|
|
357
|
+
var ParseError = /** @class */ (function (_super) {
|
|
358
|
+
__extends(ParseError, _super);
|
|
359
|
+
function ParseError(message) {
|
|
360
|
+
var _this = _super.call(this, message) || this;
|
|
361
|
+
_this.name = 'ParseError';
|
|
362
|
+
Object.setPrototypeOf(_this, ParseError.prototype);
|
|
408
363
|
return _this;
|
|
409
364
|
}
|
|
410
|
-
return
|
|
365
|
+
return ParseError;
|
|
411
366
|
}(Error));
|
|
367
|
+
/**
|
|
368
|
+
* TODO: Maybe split `ParseError` and `ApplyError`
|
|
369
|
+
*/
|
|
412
370
|
|
|
413
371
|
/**
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
* - Almost all primitives are serializable BUT:
|
|
418
|
-
* - `undefined` is not serializable
|
|
419
|
-
* - `NaN` is not serializable
|
|
420
|
-
* - Objects and arrays are serializable if all their properties are serializable
|
|
421
|
-
* - Functions are not serializable
|
|
422
|
-
* - Circular references are not serializable
|
|
423
|
-
* - `Date` objects are not serializable
|
|
424
|
-
* - `Map` and `Set` objects are not serializable
|
|
425
|
-
* - `RegExp` objects are not serializable
|
|
426
|
-
* - `Error` objects are not serializable
|
|
427
|
-
* - `Symbol` objects are not serializable
|
|
428
|
-
* - And much more...
|
|
372
|
+
* Function `validatePipelineString` will validate the if the string is a valid pipeline string
|
|
373
|
+
* 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.
|
|
429
374
|
*
|
|
430
|
-
* @
|
|
431
|
-
* @
|
|
375
|
+
* @param {string} pipelineString the candidate for a pipeline string
|
|
376
|
+
* @returns {PipelineString} the same string as input, but validated as valid
|
|
377
|
+
* @throws {ParseError} if the string is not a valid pipeline string
|
|
378
|
+
* @public exported from `@promptbook/core`
|
|
432
379
|
*/
|
|
433
|
-
function
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
if (value === undefined) {
|
|
437
|
-
throw new UnexpectedError("".concat(name, " is undefined"));
|
|
438
|
-
}
|
|
439
|
-
else if (value === null) {
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
else if (typeof value === 'boolean') {
|
|
443
|
-
return;
|
|
444
|
-
}
|
|
445
|
-
else if (typeof value === 'number' && !isNaN(value)) {
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
else if (typeof value === 'string') {
|
|
449
|
-
return;
|
|
450
|
-
}
|
|
451
|
-
else if (typeof value === 'symbol') {
|
|
452
|
-
throw new UnexpectedError("".concat(name, " is symbol"));
|
|
453
|
-
}
|
|
454
|
-
else if (typeof value === 'function') {
|
|
455
|
-
throw new UnexpectedError("".concat(name, " is function"));
|
|
456
|
-
}
|
|
457
|
-
else if (typeof value === 'object' && Array.isArray(value)) {
|
|
458
|
-
for (var i = 0; i < value.length; i++) {
|
|
459
|
-
checkSerializableAsJson({ name: "".concat(name, "[").concat(i, "]"), value: value[i], message: message });
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
else if (typeof value === 'object') {
|
|
463
|
-
if (value instanceof Date) {
|
|
464
|
-
throw new UnexpectedError(spaceTrim__default["default"](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 "); }));
|
|
465
|
-
}
|
|
466
|
-
else if (value instanceof Map) {
|
|
467
|
-
throw new UnexpectedError("".concat(name, " is Map"));
|
|
468
|
-
}
|
|
469
|
-
else if (value instanceof Set) {
|
|
470
|
-
throw new UnexpectedError("".concat(name, " is Set"));
|
|
471
|
-
}
|
|
472
|
-
else if (value instanceof RegExp) {
|
|
473
|
-
throw new UnexpectedError("".concat(name, " is RegExp"));
|
|
474
|
-
}
|
|
475
|
-
else if (value instanceof Error) {
|
|
476
|
-
throw new UnexpectedError(spaceTrim__default["default"](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 "); }));
|
|
477
|
-
}
|
|
478
|
-
else {
|
|
479
|
-
try {
|
|
480
|
-
for (var _b = __values(Object.entries(value)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
481
|
-
var _d = __read(_c.value, 2), subName = _d[0], subValue = _d[1];
|
|
482
|
-
if (subValue === undefined) {
|
|
483
|
-
// Note: undefined in object is serializable - it is just omited
|
|
484
|
-
continue;
|
|
485
|
-
}
|
|
486
|
-
checkSerializableAsJson({ name: "".concat(name, ".").concat(subName), value: subValue, message: message });
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
490
|
-
finally {
|
|
491
|
-
try {
|
|
492
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
493
|
-
}
|
|
494
|
-
finally { if (e_1) throw e_1.error; }
|
|
495
|
-
}
|
|
496
|
-
try {
|
|
497
|
-
JSON.stringify(value); // <- TODO: [0]
|
|
498
|
-
}
|
|
499
|
-
catch (error) {
|
|
500
|
-
if (!(error instanceof Error)) {
|
|
501
|
-
throw error;
|
|
502
|
-
}
|
|
503
|
-
throw new UnexpectedError(spaceTrim__default["default"](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 "); }));
|
|
504
|
-
}
|
|
505
|
-
/*
|
|
506
|
-
TODO: [0] Is there some more elegant way to check circular references?
|
|
507
|
-
const seen = new Set();
|
|
508
|
-
const stack = [{ value }];
|
|
509
|
-
while (stack.length > 0) {
|
|
510
|
-
const { value } = stack.pop()!;
|
|
511
|
-
if (typeof value === 'object' && value !== null) {
|
|
512
|
-
if (seen.has(value)) {
|
|
513
|
-
throw new UnexpectedError(`${name} has circular reference`);
|
|
514
|
-
}
|
|
515
|
-
seen.add(value);
|
|
516
|
-
if (Array.isArray(value)) {
|
|
517
|
-
stack.push(...value.map((value) => ({ value })));
|
|
518
|
-
} else {
|
|
519
|
-
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
*/
|
|
524
|
-
return;
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
else {
|
|
528
|
-
throw new UnexpectedError(spaceTrim__default["default"](function (block) { return "\n `".concat(name, "` is unknown type\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n "); }));
|
|
380
|
+
function validatePipelineString(pipelineString) {
|
|
381
|
+
if (isValidJsonString(pipelineString)) {
|
|
382
|
+
throw new ParseError('Expected a book, but got a JSON string');
|
|
529
383
|
}
|
|
384
|
+
// <- TODO: Implement the validation + add tests when the pipeline logic considered as invalid
|
|
385
|
+
return pipelineString;
|
|
530
386
|
}
|
|
531
387
|
/**
|
|
532
|
-
* TODO:
|
|
533
|
-
* TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
|
|
534
|
-
* Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
388
|
+
* TODO: [🧠][🈴] Where is the best location for this file
|
|
535
389
|
*/
|
|
536
390
|
|
|
537
391
|
/**
|
|
538
|
-
*
|
|
392
|
+
* Prettify the html code
|
|
539
393
|
*
|
|
540
|
-
* @
|
|
394
|
+
* @param content raw html code
|
|
395
|
+
* @returns formatted html code
|
|
396
|
+
* @private withing the package because of HUGE size of prettier dependency
|
|
541
397
|
*/
|
|
542
|
-
function
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
398
|
+
function prettifyMarkdown(content) {
|
|
399
|
+
try {
|
|
400
|
+
return prettier.format(content, {
|
|
401
|
+
parser: 'markdown',
|
|
402
|
+
plugins: [parserHtml__default["default"]],
|
|
403
|
+
// TODO: DRY - make some import or auto-copy of .prettierrc
|
|
404
|
+
endOfLine: 'lf',
|
|
405
|
+
tabWidth: 4,
|
|
406
|
+
singleQuote: true,
|
|
407
|
+
trailingComma: 'all',
|
|
408
|
+
arrowParens: 'always',
|
|
409
|
+
printWidth: 120,
|
|
410
|
+
htmlWhitespaceSensitivity: 'ignore',
|
|
411
|
+
jsxBracketSameLine: false,
|
|
412
|
+
bracketSpacing: true,
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
catch (error) {
|
|
416
|
+
// TODO: [🟥] Detect browser / node and make it colorfull
|
|
417
|
+
console.error('There was an error with prettifying the markdown, using the original as the fallback', {
|
|
418
|
+
error: error,
|
|
419
|
+
html: content,
|
|
420
|
+
});
|
|
421
|
+
return content;
|
|
422
|
+
}
|
|
556
423
|
}
|
|
424
|
+
|
|
557
425
|
/**
|
|
558
|
-
*
|
|
426
|
+
* Makes first letter of a string uppercase
|
|
427
|
+
*
|
|
428
|
+
* @public exported from `@promptbook/utils`
|
|
559
429
|
*/
|
|
430
|
+
function capitalize(word) {
|
|
431
|
+
return word.substring(0, 1).toUpperCase() + word.substring(1);
|
|
432
|
+
}
|
|
560
433
|
|
|
561
434
|
/**
|
|
562
|
-
*
|
|
435
|
+
* Converts promptbook in JSON format to string format
|
|
563
436
|
*
|
|
564
|
-
*
|
|
565
|
-
*
|
|
566
|
-
*
|
|
567
|
-
*
|
|
568
|
-
*
|
|
569
|
-
* Note: This function does not mutates the given object
|
|
570
|
-
*
|
|
571
|
-
* @returns The same type of object as the input but read-only and re-ordered
|
|
572
|
-
* @public exported from `@promptbook/utils`
|
|
437
|
+
* @deprecated TODO: [🥍][🧠] Backup original files in `PipelineJson` same as in Promptbook.studio
|
|
438
|
+
* @param pipelineJson Promptbook in JSON format (.book.json)
|
|
439
|
+
* @returns Promptbook in string format (.book.md)
|
|
440
|
+
* @public exported from `@promptbook/core`
|
|
573
441
|
*/
|
|
574
|
-
function
|
|
575
|
-
var
|
|
576
|
-
|
|
577
|
-
var
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
442
|
+
function pipelineJsonToString(pipelineJson) {
|
|
443
|
+
var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e, e_6, _f;
|
|
444
|
+
var title = pipelineJson.title, pipelineUrl = pipelineJson.pipelineUrl, bookVersion = pipelineJson.bookVersion, description = pipelineJson.description, parameters = pipelineJson.parameters, tasks = pipelineJson.tasks;
|
|
445
|
+
var pipelineString = "# ".concat(title);
|
|
446
|
+
if (description) {
|
|
447
|
+
pipelineString += '\n\n';
|
|
448
|
+
pipelineString += description;
|
|
449
|
+
}
|
|
450
|
+
var commands = [];
|
|
451
|
+
if (pipelineUrl) {
|
|
452
|
+
commands.push("PIPELINE URL ".concat(pipelineUrl));
|
|
453
|
+
}
|
|
454
|
+
if (bookVersion !== "undefined") {
|
|
455
|
+
commands.push("BOOK VERSION ".concat(bookVersion));
|
|
456
|
+
}
|
|
457
|
+
// TODO: [main] !!5 This increases size of the bundle and is probbably not necessary
|
|
458
|
+
pipelineString = prettifyMarkdown(pipelineString);
|
|
459
|
+
try {
|
|
460
|
+
for (var _g = __values(parameters.filter(function (_a) {
|
|
461
|
+
var isInput = _a.isInput;
|
|
462
|
+
return isInput;
|
|
463
|
+
})), _h = _g.next(); !_h.done; _h = _g.next()) {
|
|
464
|
+
var parameter = _h.value;
|
|
465
|
+
commands.push("INPUT PARAMETER ".concat(taskParameterJsonToString(parameter)));
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
469
|
+
finally {
|
|
470
|
+
try {
|
|
471
|
+
if (_h && !_h.done && (_a = _g.return)) _a.call(_g);
|
|
472
|
+
}
|
|
473
|
+
finally { if (e_1) throw e_1.error; }
|
|
474
|
+
}
|
|
475
|
+
try {
|
|
476
|
+
for (var _j = __values(parameters.filter(function (_a) {
|
|
477
|
+
var isOutput = _a.isOutput;
|
|
478
|
+
return isOutput;
|
|
479
|
+
})), _k = _j.next(); !_k.done; _k = _j.next()) {
|
|
480
|
+
var parameter = _k.value;
|
|
481
|
+
commands.push("OUTPUT PARAMETER ".concat(taskParameterJsonToString(parameter)));
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
485
|
+
finally {
|
|
486
|
+
try {
|
|
487
|
+
if (_k && !_k.done && (_b = _j.return)) _b.call(_j);
|
|
488
|
+
}
|
|
489
|
+
finally { if (e_2) throw e_2.error; }
|
|
490
|
+
}
|
|
491
|
+
pipelineString += '\n\n';
|
|
492
|
+
pipelineString += commands.map(function (command) { return "- ".concat(command); }).join('\n');
|
|
493
|
+
try {
|
|
494
|
+
for (var tasks_1 = __values(tasks), tasks_1_1 = tasks_1.next(); !tasks_1_1.done; tasks_1_1 = tasks_1.next()) {
|
|
495
|
+
var task = tasks_1_1.value;
|
|
496
|
+
var
|
|
497
|
+
/* Note: Not using:> name, */
|
|
498
|
+
title_1 = task.title, description_1 = task.description,
|
|
499
|
+
/* Note: dependentParameterNames, */
|
|
500
|
+
jokers = task.jokerParameterNames, taskType = task.taskType, content = task.content, postprocessing = task.postprocessingFunctionNames, expectations = task.expectations, format = task.format, resultingParameterName = task.resultingParameterName;
|
|
501
|
+
pipelineString += '\n\n';
|
|
502
|
+
pipelineString += "## ".concat(title_1);
|
|
503
|
+
if (description_1) {
|
|
504
|
+
pipelineString += '\n\n';
|
|
505
|
+
pipelineString += description_1;
|
|
506
|
+
}
|
|
507
|
+
var commands_1 = [];
|
|
508
|
+
var contentLanguage = 'text';
|
|
509
|
+
if (taskType === 'PROMPT_TASK') {
|
|
510
|
+
var modelRequirements = task.modelRequirements;
|
|
511
|
+
var _l = modelRequirements || {}, modelName = _l.modelName, modelVariant = _l.modelVariant;
|
|
512
|
+
// Note: Do nothing, it is default
|
|
513
|
+
// commands.push(`PROMPT`);
|
|
514
|
+
if (modelVariant) {
|
|
515
|
+
commands_1.push("MODEL VARIANT ".concat(capitalize(modelVariant)));
|
|
516
|
+
}
|
|
517
|
+
if (modelName) {
|
|
518
|
+
commands_1.push("MODEL NAME `".concat(modelName, "`"));
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
else if (taskType === 'SIMPLE_TASK') {
|
|
522
|
+
commands_1.push("SIMPLE TEMPLATE");
|
|
523
|
+
// Note: Nothing special here
|
|
524
|
+
}
|
|
525
|
+
else if (taskType === 'SCRIPT_TASK') {
|
|
526
|
+
commands_1.push("SCRIPT");
|
|
527
|
+
if (task.contentLanguage) {
|
|
528
|
+
contentLanguage = task.contentLanguage;
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
contentLanguage = '';
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
else if (taskType === 'DIALOG_TASK') {
|
|
535
|
+
commands_1.push("DIALOG");
|
|
536
|
+
// Note: Nothing special here
|
|
537
|
+
} // <- }else if([🅱]
|
|
538
|
+
if (jokers) {
|
|
539
|
+
try {
|
|
540
|
+
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()) {
|
|
541
|
+
var joker = jokers_1_1.value;
|
|
542
|
+
commands_1.push("JOKER {".concat(joker, "}"));
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
546
|
+
finally {
|
|
547
|
+
try {
|
|
548
|
+
if (jokers_1_1 && !jokers_1_1.done && (_d = jokers_1.return)) _d.call(jokers_1);
|
|
549
|
+
}
|
|
550
|
+
finally { if (e_4) throw e_4.error; }
|
|
551
|
+
}
|
|
552
|
+
} /* not else */
|
|
553
|
+
if (postprocessing) {
|
|
554
|
+
try {
|
|
555
|
+
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()) {
|
|
556
|
+
var postprocessingFunctionName = postprocessing_1_1.value;
|
|
557
|
+
commands_1.push("POSTPROCESSING `".concat(postprocessingFunctionName, "`"));
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
561
|
+
finally {
|
|
562
|
+
try {
|
|
563
|
+
if (postprocessing_1_1 && !postprocessing_1_1.done && (_e = postprocessing_1.return)) _e.call(postprocessing_1);
|
|
564
|
+
}
|
|
565
|
+
finally { if (e_5) throw e_5.error; }
|
|
566
|
+
}
|
|
567
|
+
} /* not else */
|
|
568
|
+
if (expectations) {
|
|
569
|
+
try {
|
|
570
|
+
for (var _m = (e_6 = void 0, __values(Object.entries(expectations))), _o = _m.next(); !_o.done; _o = _m.next()) {
|
|
571
|
+
var _p = __read(_o.value, 2), unit = _p[0], _q = _p[1], min = _q.min, max = _q.max;
|
|
572
|
+
if (min === max) {
|
|
573
|
+
commands_1.push("EXPECT EXACTLY ".concat(min, " ").concat(capitalize(unit + (min > 1 ? 's' : ''))));
|
|
574
|
+
}
|
|
575
|
+
else {
|
|
576
|
+
if (min !== undefined) {
|
|
577
|
+
commands_1.push("EXPECT MIN ".concat(min, " ").concat(capitalize(unit + (min > 1 ? 's' : ''))));
|
|
578
|
+
} /* not else */
|
|
579
|
+
if (max !== undefined) {
|
|
580
|
+
commands_1.push("EXPECT MAX ".concat(max, " ").concat(capitalize(unit + (max > 1 ? 's' : ''))));
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
586
|
+
finally {
|
|
587
|
+
try {
|
|
588
|
+
if (_o && !_o.done && (_f = _m.return)) _f.call(_m);
|
|
589
|
+
}
|
|
590
|
+
finally { if (e_6) throw e_6.error; }
|
|
591
|
+
}
|
|
592
|
+
} /* not else */
|
|
593
|
+
if (format) {
|
|
594
|
+
if (format === 'JSON') {
|
|
595
|
+
// TODO: @deprecated remove
|
|
596
|
+
commands_1.push("FORMAT JSON");
|
|
597
|
+
}
|
|
598
|
+
} /* not else */
|
|
599
|
+
pipelineString += '\n\n';
|
|
600
|
+
pipelineString += commands_1.map(function (command) { return "- ".concat(command); }).join('\n');
|
|
601
|
+
pipelineString += '\n\n';
|
|
602
|
+
pipelineString += '```' + contentLanguage;
|
|
603
|
+
pipelineString += '\n';
|
|
604
|
+
pipelineString += spaceTrim__default["default"](content);
|
|
605
|
+
// <- TODO: [main] !!3 Escape
|
|
606
|
+
// <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
|
|
607
|
+
pipelineString += '\n';
|
|
608
|
+
pipelineString += '```';
|
|
609
|
+
pipelineString += '\n\n';
|
|
610
|
+
pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: [main] !!3 If the parameter here has description, add it and use taskParameterJsonToString
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
614
|
+
finally {
|
|
615
|
+
try {
|
|
616
|
+
if (tasks_1_1 && !tasks_1_1.done && (_c = tasks_1.return)) _c.call(tasks_1);
|
|
617
|
+
}
|
|
618
|
+
finally { if (e_3) throw e_3.error; }
|
|
619
|
+
}
|
|
620
|
+
return validatePipelineString(pipelineString);
|
|
590
621
|
}
|
|
591
622
|
/**
|
|
592
|
-
*
|
|
623
|
+
* @private internal utility of `pipelineJsonToString`
|
|
593
624
|
*/
|
|
594
|
-
|
|
625
|
+
function taskParameterJsonToString(taskParameterJson) {
|
|
626
|
+
var name = taskParameterJson.name, description = taskParameterJson.description;
|
|
627
|
+
var parameterString = "{".concat(name, "}");
|
|
628
|
+
if (description) {
|
|
629
|
+
parameterString = "".concat(parameterString, " ").concat(description);
|
|
630
|
+
}
|
|
631
|
+
return parameterString;
|
|
632
|
+
}
|
|
595
633
|
/**
|
|
596
|
-
*
|
|
597
|
-
*
|
|
598
|
-
*
|
|
634
|
+
* TODO: [🛋] Implement new features and commands into `pipelineJsonToString` + `taskParameterJsonToString` , use `stringifyCommand`
|
|
635
|
+
* TODO: [🧠] Is there a way to auto-detect missing features in pipelineJsonToString
|
|
636
|
+
* TODO: [🏛] Maybe make some markdown builder
|
|
637
|
+
* TODO: [🏛] Escape all
|
|
638
|
+
* TODO: [🧠] Should be in generated .book.md file GENERATOR_WARNING
|
|
599
639
|
*/
|
|
600
|
-
|
|
601
|
-
// Note: [🍙] In this order will be pipeline serialized
|
|
602
|
-
'title',
|
|
603
|
-
'pipelineUrl',
|
|
604
|
-
'bookVersion',
|
|
605
|
-
'description',
|
|
606
|
-
'formfactorName',
|
|
607
|
-
'parameters',
|
|
608
|
-
'tasks',
|
|
609
|
-
'personas',
|
|
610
|
-
'preparations',
|
|
611
|
-
'knowledgeSources',
|
|
612
|
-
'knowledgePieces',
|
|
613
|
-
'sources', // <- TODO: [🧠] Where should the `sources` be
|
|
614
|
-
];
|
|
640
|
+
|
|
615
641
|
/**
|
|
616
|
-
*
|
|
642
|
+
* Orders JSON object by keys
|
|
617
643
|
*
|
|
618
|
-
* @
|
|
644
|
+
* @returns The same type of object as the input re-ordered
|
|
645
|
+
* @public exported from `@promptbook/utils`
|
|
619
646
|
*/
|
|
620
|
-
|
|
647
|
+
function orderJson(options) {
|
|
648
|
+
var value = options.value, order = options.order;
|
|
649
|
+
var orderedValue = __assign(__assign({}, (order === undefined ? {} : Object.fromEntries(order.map(function (key) { return [key, undefined]; })))), value);
|
|
650
|
+
return orderedValue;
|
|
651
|
+
}
|
|
652
|
+
|
|
621
653
|
/**
|
|
622
|
-
*
|
|
654
|
+
* Freezes the given object and all its nested objects recursively
|
|
623
655
|
*
|
|
624
|
-
*
|
|
625
|
-
|
|
626
|
-
var RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
|
|
627
|
-
/**
|
|
628
|
-
* @@@
|
|
656
|
+
* Note: `$` is used to indicate that this function is not a pure function - it mutates given object
|
|
657
|
+
* Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
|
|
629
658
|
*
|
|
630
|
-
* @
|
|
659
|
+
* @returns The same object as the input, but deeply frozen
|
|
660
|
+
* @public exported from `@promptbook/utils`
|
|
631
661
|
*/
|
|
632
|
-
|
|
662
|
+
function $deepFreeze(objectValue) {
|
|
663
|
+
var e_1, _a;
|
|
664
|
+
if (Array.isArray(objectValue)) {
|
|
665
|
+
return Object.freeze(objectValue.map(function (item) { return $deepFreeze(item); }));
|
|
666
|
+
}
|
|
667
|
+
var propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
668
|
+
try {
|
|
669
|
+
for (var propertyNames_1 = __values(propertyNames), propertyNames_1_1 = propertyNames_1.next(); !propertyNames_1_1.done; propertyNames_1_1 = propertyNames_1.next()) {
|
|
670
|
+
var propertyName = propertyNames_1_1.value;
|
|
671
|
+
var value = objectValue[propertyName];
|
|
672
|
+
if (value && typeof value === 'object') {
|
|
673
|
+
$deepFreeze(value);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
678
|
+
finally {
|
|
679
|
+
try {
|
|
680
|
+
if (propertyNames_1_1 && !propertyNames_1_1.done && (_a = propertyNames_1.return)) _a.call(propertyNames_1);
|
|
681
|
+
}
|
|
682
|
+
finally { if (e_1) throw e_1.error; }
|
|
683
|
+
}
|
|
684
|
+
Object.freeze(objectValue);
|
|
685
|
+
return objectValue;
|
|
686
|
+
}
|
|
633
687
|
/**
|
|
634
|
-
*
|
|
635
|
-
*
|
|
636
|
-
* @public exported from `@promptbook/core`
|
|
688
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
637
689
|
*/
|
|
638
|
-
|
|
639
|
-
name: 'RESERVED_PARAMETER_NAMES',
|
|
640
|
-
message: "The names of the parameters that are reserved for special purposes",
|
|
641
|
-
value: [
|
|
642
|
-
'content',
|
|
643
|
-
'context',
|
|
644
|
-
'knowledge',
|
|
645
|
-
'examples',
|
|
646
|
-
'modelName',
|
|
647
|
-
'currentDate',
|
|
648
|
-
// <- TODO: list here all command names
|
|
649
|
-
// <- TODO: Add more like 'date', 'modelName',...
|
|
650
|
-
// <- TODO: Add [emoji] + instructions ACRY when adding new reserved parameter
|
|
651
|
-
],
|
|
652
|
-
});
|
|
690
|
+
|
|
653
691
|
/**
|
|
654
|
-
*
|
|
692
|
+
* Make error report URL for the given error
|
|
693
|
+
*
|
|
694
|
+
* @private private within the repository
|
|
655
695
|
*/
|
|
696
|
+
function getErrorReportUrl(error) {
|
|
697
|
+
var report = {
|
|
698
|
+
title: "\uD83D\uDC1C Error report from ".concat(NAME),
|
|
699
|
+
body: spaceTrim__default["default"](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 "); }),
|
|
700
|
+
};
|
|
701
|
+
var reportUrl = new URL("https://github.com/webgptorg/promptbook/issues/new");
|
|
702
|
+
reportUrl.searchParams.set('labels', 'bug');
|
|
703
|
+
reportUrl.searchParams.set('assignees', ADMIN_GITHUB_NAME);
|
|
704
|
+
reportUrl.searchParams.set('title', report.title);
|
|
705
|
+
reportUrl.searchParams.set('body', report.body);
|
|
706
|
+
return reportUrl;
|
|
707
|
+
}
|
|
656
708
|
|
|
657
709
|
/**
|
|
658
|
-
* This error type indicates that
|
|
710
|
+
* This error type indicates that the error should not happen and its last check before crashing with some other error
|
|
659
711
|
*
|
|
660
712
|
* @public exported from `@promptbook/core`
|
|
661
713
|
*/
|
|
662
|
-
var
|
|
663
|
-
__extends(
|
|
664
|
-
function
|
|
665
|
-
var _this = _super.call(this, spaceTrim.spaceTrim(function (block) { return "\n ".concat(block(message), "\n\n Note:
|
|
666
|
-
_this.name = '
|
|
667
|
-
Object.setPrototypeOf(_this,
|
|
714
|
+
var UnexpectedError = /** @class */ (function (_super) {
|
|
715
|
+
__extends(UnexpectedError, _super);
|
|
716
|
+
function UnexpectedError(message) {
|
|
717
|
+
var _this = _super.call(this, spaceTrim.spaceTrim(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;
|
|
718
|
+
_this.name = 'UnexpectedError';
|
|
719
|
+
Object.setPrototypeOf(_this, UnexpectedError.prototype);
|
|
668
720
|
return _this;
|
|
669
721
|
}
|
|
670
|
-
return
|
|
722
|
+
return UnexpectedError;
|
|
671
723
|
}(Error));
|
|
672
724
|
|
|
673
725
|
/**
|
|
674
|
-
*
|
|
726
|
+
* Checks if the value is [🚉] serializable as JSON
|
|
727
|
+
* If not, throws an UnexpectedError with a rich error message and tracking
|
|
675
728
|
*
|
|
676
|
-
*
|
|
677
|
-
*
|
|
678
|
-
*
|
|
729
|
+
* - Almost all primitives are serializable BUT:
|
|
730
|
+
* - `undefined` is not serializable
|
|
731
|
+
* - `NaN` is not serializable
|
|
732
|
+
* - Objects and arrays are serializable if all their properties are serializable
|
|
733
|
+
* - Functions are not serializable
|
|
734
|
+
* - Circular references are not serializable
|
|
735
|
+
* - `Date` objects are not serializable
|
|
736
|
+
* - `Map` and `Set` objects are not serializable
|
|
737
|
+
* - `RegExp` objects are not serializable
|
|
738
|
+
* - `Error` objects are not serializable
|
|
739
|
+
* - `Symbol` objects are not serializable
|
|
740
|
+
* - And much more...
|
|
741
|
+
*
|
|
742
|
+
* @throws UnexpectedError if the value is not serializable as JSON
|
|
679
743
|
* @public exported from `@promptbook/utils`
|
|
680
|
-
* @deprecated [🪂] Use queues instead
|
|
681
744
|
*/
|
|
682
|
-
function
|
|
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
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
case 7:
|
|
735
|
-
try {
|
|
736
|
-
if (_c && !_c.done && (_d = _b.return)) _d.call(_b);
|
|
745
|
+
function checkSerializableAsJson(options) {
|
|
746
|
+
var e_1, _a;
|
|
747
|
+
var value = options.value, name = options.name, message = options.message;
|
|
748
|
+
if (value === undefined) {
|
|
749
|
+
throw new UnexpectedError("".concat(name, " is undefined"));
|
|
750
|
+
}
|
|
751
|
+
else if (value === null) {
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
else if (typeof value === 'boolean') {
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
else if (typeof value === 'number' && !isNaN(value)) {
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
else if (typeof value === 'string') {
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
else if (typeof value === 'symbol') {
|
|
764
|
+
throw new UnexpectedError("".concat(name, " is symbol"));
|
|
765
|
+
}
|
|
766
|
+
else if (typeof value === 'function') {
|
|
767
|
+
throw new UnexpectedError("".concat(name, " is function"));
|
|
768
|
+
}
|
|
769
|
+
else if (typeof value === 'object' && Array.isArray(value)) {
|
|
770
|
+
for (var i = 0; i < value.length; i++) {
|
|
771
|
+
checkSerializableAsJson({ name: "".concat(name, "[").concat(i, "]"), value: value[i], message: message });
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
else if (typeof value === 'object') {
|
|
775
|
+
if (value instanceof Date) {
|
|
776
|
+
throw new UnexpectedError(spaceTrim__default["default"](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 "); }));
|
|
777
|
+
}
|
|
778
|
+
else if (value instanceof Map) {
|
|
779
|
+
throw new UnexpectedError("".concat(name, " is Map"));
|
|
780
|
+
}
|
|
781
|
+
else if (value instanceof Set) {
|
|
782
|
+
throw new UnexpectedError("".concat(name, " is Set"));
|
|
783
|
+
}
|
|
784
|
+
else if (value instanceof RegExp) {
|
|
785
|
+
throw new UnexpectedError("".concat(name, " is RegExp"));
|
|
786
|
+
}
|
|
787
|
+
else if (value instanceof Error) {
|
|
788
|
+
throw new UnexpectedError(spaceTrim__default["default"](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 "); }));
|
|
789
|
+
}
|
|
790
|
+
else {
|
|
791
|
+
try {
|
|
792
|
+
for (var _b = __values(Object.entries(value)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
793
|
+
var _d = __read(_c.value, 2), subName = _d[0], subValue = _d[1];
|
|
794
|
+
if (subValue === undefined) {
|
|
795
|
+
// Note: undefined in object is serializable - it is just omited
|
|
796
|
+
continue;
|
|
737
797
|
}
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
case 8: return [4 /*yield*/, Promise.all(tasks)];
|
|
741
|
-
case 9:
|
|
742
|
-
_e.sent();
|
|
743
|
-
return [2 /*return*/];
|
|
798
|
+
checkSerializableAsJson({ name: "".concat(name, ".").concat(subName), value: subValue, message: message });
|
|
799
|
+
}
|
|
744
800
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
/**
|
|
750
|
-
* Represents the usage with no resources consumed
|
|
751
|
-
*
|
|
752
|
-
* @public exported from `@promptbook/core`
|
|
753
|
-
*/
|
|
754
|
-
var ZERO_USAGE = $deepFreeze({
|
|
755
|
-
price: { value: 0 },
|
|
756
|
-
input: {
|
|
757
|
-
tokensCount: { value: 0 },
|
|
758
|
-
charactersCount: { value: 0 },
|
|
759
|
-
wordsCount: { value: 0 },
|
|
760
|
-
sentencesCount: { value: 0 },
|
|
761
|
-
linesCount: { value: 0 },
|
|
762
|
-
paragraphsCount: { value: 0 },
|
|
763
|
-
pagesCount: { value: 0 },
|
|
764
|
-
},
|
|
765
|
-
output: {
|
|
766
|
-
tokensCount: { value: 0 },
|
|
767
|
-
charactersCount: { value: 0 },
|
|
768
|
-
wordsCount: { value: 0 },
|
|
769
|
-
sentencesCount: { value: 0 },
|
|
770
|
-
linesCount: { value: 0 },
|
|
771
|
-
paragraphsCount: { value: 0 },
|
|
772
|
-
pagesCount: { value: 0 },
|
|
773
|
-
},
|
|
774
|
-
});
|
|
775
|
-
/**
|
|
776
|
-
* Represents the usage with unknown resources consumed
|
|
777
|
-
*
|
|
778
|
-
* @public exported from `@promptbook/core`
|
|
779
|
-
*/
|
|
780
|
-
$deepFreeze({
|
|
781
|
-
price: { value: 0, isUncertain: true },
|
|
782
|
-
input: {
|
|
783
|
-
tokensCount: { value: 0, isUncertain: true },
|
|
784
|
-
charactersCount: { value: 0, isUncertain: true },
|
|
785
|
-
wordsCount: { value: 0, isUncertain: true },
|
|
786
|
-
sentencesCount: { value: 0, isUncertain: true },
|
|
787
|
-
linesCount: { value: 0, isUncertain: true },
|
|
788
|
-
paragraphsCount: { value: 0, isUncertain: true },
|
|
789
|
-
pagesCount: { value: 0, isUncertain: true },
|
|
790
|
-
},
|
|
791
|
-
output: {
|
|
792
|
-
tokensCount: { value: 0, isUncertain: true },
|
|
793
|
-
charactersCount: { value: 0, isUncertain: true },
|
|
794
|
-
wordsCount: { value: 0, isUncertain: true },
|
|
795
|
-
sentencesCount: { value: 0, isUncertain: true },
|
|
796
|
-
linesCount: { value: 0, isUncertain: true },
|
|
797
|
-
paragraphsCount: { value: 0, isUncertain: true },
|
|
798
|
-
pagesCount: { value: 0, isUncertain: true },
|
|
799
|
-
},
|
|
800
|
-
});
|
|
801
|
-
/**
|
|
802
|
-
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
803
|
-
*/
|
|
804
|
-
|
|
805
|
-
/**
|
|
806
|
-
* Function `addUsage` will add multiple usages into one
|
|
807
|
-
*
|
|
808
|
-
* Note: If you provide 0 values, it returns ZERO_USAGE
|
|
809
|
-
*
|
|
810
|
-
* @public exported from `@promptbook/core`
|
|
811
|
-
*/
|
|
812
|
-
function addUsage() {
|
|
813
|
-
var usageItems = [];
|
|
814
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
815
|
-
usageItems[_i] = arguments[_i];
|
|
816
|
-
}
|
|
817
|
-
return usageItems.reduce(function (acc, item) {
|
|
818
|
-
var e_1, _a, e_2, _b;
|
|
819
|
-
var _c;
|
|
820
|
-
acc.price.value += ((_c = item.price) === null || _c === void 0 ? void 0 : _c.value) || 0;
|
|
821
|
-
try {
|
|
822
|
-
for (var _d = __values(Object.keys(acc.input)), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
823
|
-
var key = _e.value;
|
|
824
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
825
|
-
//@ts-ignore
|
|
826
|
-
if (item.input[key]) {
|
|
827
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
828
|
-
//@ts-ignore
|
|
829
|
-
acc.input[key].value += item.input[key].value || 0;
|
|
830
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
831
|
-
//@ts-ignore
|
|
832
|
-
if (item.input[key].isUncertain) {
|
|
833
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
834
|
-
//@ts-ignore
|
|
835
|
-
acc.input[key].isUncertain = true;
|
|
836
|
-
}
|
|
801
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
802
|
+
finally {
|
|
803
|
+
try {
|
|
804
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
837
805
|
}
|
|
806
|
+
finally { if (e_1) throw e_1.error; }
|
|
838
807
|
}
|
|
839
|
-
}
|
|
840
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
841
|
-
finally {
|
|
842
808
|
try {
|
|
843
|
-
|
|
809
|
+
JSON.stringify(value); // <- TODO: [0]
|
|
844
810
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
for (var _f = __values(Object.keys(acc.output)), _g = _f.next(); !_g.done; _g = _f.next()) {
|
|
849
|
-
var key = _g.value;
|
|
850
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
851
|
-
//@ts-ignore
|
|
852
|
-
if (item.output[key]) {
|
|
853
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
854
|
-
//@ts-ignore
|
|
855
|
-
acc.output[key].value += item.output[key].value || 0;
|
|
856
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
857
|
-
//@ts-ignore
|
|
858
|
-
if (item.output[key].isUncertain) {
|
|
859
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
860
|
-
//@ts-ignore
|
|
861
|
-
acc.output[key].isUncertain = true;
|
|
862
|
-
}
|
|
811
|
+
catch (error) {
|
|
812
|
+
if (!(error instanceof Error)) {
|
|
813
|
+
throw error;
|
|
863
814
|
}
|
|
815
|
+
throw new UnexpectedError(spaceTrim__default["default"](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 "); }));
|
|
864
816
|
}
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
817
|
+
/*
|
|
818
|
+
TODO: [0] Is there some more elegant way to check circular references?
|
|
819
|
+
const seen = new Set();
|
|
820
|
+
const stack = [{ value }];
|
|
821
|
+
while (stack.length > 0) {
|
|
822
|
+
const { value } = stack.pop()!;
|
|
823
|
+
if (typeof value === 'object' && value !== null) {
|
|
824
|
+
if (seen.has(value)) {
|
|
825
|
+
throw new UnexpectedError(`${name} has circular reference`);
|
|
826
|
+
}
|
|
827
|
+
seen.add(value);
|
|
828
|
+
if (Array.isArray(value)) {
|
|
829
|
+
stack.push(...value.map((value) => ({ value })));
|
|
830
|
+
} else {
|
|
831
|
+
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
832
|
+
}
|
|
833
|
+
}
|
|
870
834
|
}
|
|
871
|
-
|
|
835
|
+
*/
|
|
836
|
+
return;
|
|
872
837
|
}
|
|
873
|
-
return acc;
|
|
874
|
-
}, deepClone(ZERO_USAGE));
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
/**
|
|
878
|
-
* Intercepts LLM tools and counts total usage of the tools
|
|
879
|
-
*
|
|
880
|
-
* @param llmTools LLM tools to be intercepted with usage counting
|
|
881
|
-
* @returns LLM tools with same functionality with added total cost counting
|
|
882
|
-
* @public exported from `@promptbook/core`
|
|
883
|
-
*/
|
|
884
|
-
function countTotalUsage(llmTools) {
|
|
885
|
-
var _this = this;
|
|
886
|
-
var totalUsage = ZERO_USAGE;
|
|
887
|
-
var proxyTools = {
|
|
888
|
-
get title() {
|
|
889
|
-
// TODO: [🧠] Maybe put here some suffix
|
|
890
|
-
return llmTools.title;
|
|
891
|
-
},
|
|
892
|
-
get description() {
|
|
893
|
-
// TODO: [🧠] Maybe put here some suffix
|
|
894
|
-
return llmTools.description;
|
|
895
|
-
},
|
|
896
|
-
checkConfiguration: function () {
|
|
897
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
898
|
-
return __generator(this, function (_a) {
|
|
899
|
-
return [2 /*return*/, /* not await */ llmTools.checkConfiguration()];
|
|
900
|
-
});
|
|
901
|
-
});
|
|
902
|
-
},
|
|
903
|
-
listModels: function () {
|
|
904
|
-
return /* not await */ llmTools.listModels();
|
|
905
|
-
},
|
|
906
|
-
getTotalUsage: function () {
|
|
907
|
-
// <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
|
|
908
|
-
return totalUsage;
|
|
909
|
-
},
|
|
910
|
-
};
|
|
911
|
-
if (llmTools.callChatModel !== undefined) {
|
|
912
|
-
proxyTools.callChatModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
|
|
913
|
-
var promptResult;
|
|
914
|
-
return __generator(this, function (_a) {
|
|
915
|
-
switch (_a.label) {
|
|
916
|
-
case 0: return [4 /*yield*/, llmTools.callChatModel(prompt)];
|
|
917
|
-
case 1:
|
|
918
|
-
promptResult = _a.sent();
|
|
919
|
-
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
920
|
-
return [2 /*return*/, promptResult];
|
|
921
|
-
}
|
|
922
|
-
});
|
|
923
|
-
}); };
|
|
924
|
-
}
|
|
925
|
-
if (llmTools.callCompletionModel !== undefined) {
|
|
926
|
-
proxyTools.callCompletionModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
|
|
927
|
-
var promptResult;
|
|
928
|
-
return __generator(this, function (_a) {
|
|
929
|
-
switch (_a.label) {
|
|
930
|
-
case 0: return [4 /*yield*/, llmTools.callCompletionModel(prompt)];
|
|
931
|
-
case 1:
|
|
932
|
-
promptResult = _a.sent();
|
|
933
|
-
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
934
|
-
return [2 /*return*/, promptResult];
|
|
935
|
-
}
|
|
936
|
-
});
|
|
937
|
-
}); };
|
|
938
838
|
}
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
var promptResult;
|
|
942
|
-
return __generator(this, function (_a) {
|
|
943
|
-
switch (_a.label) {
|
|
944
|
-
case 0: return [4 /*yield*/, llmTools.callEmbeddingModel(prompt)];
|
|
945
|
-
case 1:
|
|
946
|
-
promptResult = _a.sent();
|
|
947
|
-
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
948
|
-
return [2 /*return*/, promptResult];
|
|
949
|
-
}
|
|
950
|
-
});
|
|
951
|
-
}); };
|
|
839
|
+
else {
|
|
840
|
+
throw new UnexpectedError(spaceTrim__default["default"](function (block) { return "\n `".concat(name, "` is unknown type\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n "); }));
|
|
952
841
|
}
|
|
953
|
-
// <- Note: [🤖]
|
|
954
|
-
return proxyTools;
|
|
955
842
|
}
|
|
956
843
|
/**
|
|
957
|
-
* TODO:
|
|
958
|
-
* TODO: [🧠]
|
|
959
|
-
*
|
|
960
|
-
* > const [llmToolsWithUsage,getUsage] = countTotalUsage(llmTools);
|
|
961
|
-
* TODO: [👷♂️] @@@ Manual about construction of llmTools
|
|
844
|
+
* TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
845
|
+
* TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
846
|
+
* Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
962
847
|
*/
|
|
963
848
|
|
|
964
849
|
/**
|
|
965
|
-
*
|
|
850
|
+
* @@@
|
|
966
851
|
*
|
|
967
|
-
* @public exported from `@promptbook/
|
|
852
|
+
* @public exported from `@promptbook/utils`
|
|
853
|
+
*/
|
|
854
|
+
function deepClone(objectValue) {
|
|
855
|
+
return JSON.parse(JSON.stringify(objectValue));
|
|
856
|
+
/*
|
|
857
|
+
TODO: [🧠] Is there a better implementation?
|
|
858
|
+
> const propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
859
|
+
> for (const propertyName of propertyNames) {
|
|
860
|
+
> const value = (objectValue as really_any)[propertyName];
|
|
861
|
+
> if (value && typeof value === 'object') {
|
|
862
|
+
> deepClone(value);
|
|
863
|
+
> }
|
|
864
|
+
> }
|
|
865
|
+
> return Object.assign({}, objectValue);
|
|
866
|
+
*/
|
|
867
|
+
}
|
|
868
|
+
/**
|
|
869
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
968
870
|
*/
|
|
969
|
-
var PipelineExecutionError = /** @class */ (function (_super) {
|
|
970
|
-
__extends(PipelineExecutionError, _super);
|
|
971
|
-
function PipelineExecutionError(message) {
|
|
972
|
-
var _this = _super.call(this, message) || this;
|
|
973
|
-
_this.name = 'PipelineExecutionError';
|
|
974
|
-
Object.setPrototypeOf(_this, PipelineExecutionError.prototype);
|
|
975
|
-
return _this;
|
|
976
|
-
}
|
|
977
|
-
return PipelineExecutionError;
|
|
978
|
-
}(Error));
|
|
979
871
|
|
|
980
872
|
/**
|
|
981
|
-
*
|
|
873
|
+
* Utility to export a JSON object from a function
|
|
982
874
|
*
|
|
983
|
-
*
|
|
984
|
-
*
|
|
875
|
+
* 1) Checks if the value is serializable as JSON
|
|
876
|
+
* 2) Makes a deep clone of the object
|
|
877
|
+
* 2) Orders the object properties
|
|
878
|
+
* 2) Deeply freezes the cloned object
|
|
879
|
+
*
|
|
880
|
+
* Note: This function does not mutates the given object
|
|
881
|
+
*
|
|
882
|
+
* @returns The same type of object as the input but read-only and re-ordered
|
|
883
|
+
* @public exported from `@promptbook/utils`
|
|
985
884
|
*/
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
return 'Multiple LLM Providers';
|
|
1000
|
-
},
|
|
1001
|
-
enumerable: false,
|
|
1002
|
-
configurable: true
|
|
1003
|
-
});
|
|
1004
|
-
Object.defineProperty(MultipleLlmExecutionTools.prototype, "description", {
|
|
1005
|
-
get: function () {
|
|
1006
|
-
return this.llmExecutionTools.map(function (_a, index) {
|
|
1007
|
-
var title = _a.title;
|
|
1008
|
-
return "".concat(index + 1, ") `").concat(title, "`");
|
|
1009
|
-
}).join('\n');
|
|
1010
|
-
},
|
|
1011
|
-
enumerable: false,
|
|
1012
|
-
configurable: true
|
|
1013
|
-
});
|
|
1014
|
-
/**
|
|
1015
|
-
* Check the configuration of all execution tools
|
|
1016
|
-
*/
|
|
1017
|
-
MultipleLlmExecutionTools.prototype.checkConfiguration = function () {
|
|
1018
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1019
|
-
var _a, _b, llmExecutionTools, e_1_1;
|
|
1020
|
-
var e_1, _c;
|
|
1021
|
-
return __generator(this, function (_d) {
|
|
1022
|
-
switch (_d.label) {
|
|
1023
|
-
case 0:
|
|
1024
|
-
_d.trys.push([0, 5, 6, 7]);
|
|
1025
|
-
_a = __values(this.llmExecutionTools), _b = _a.next();
|
|
1026
|
-
_d.label = 1;
|
|
1027
|
-
case 1:
|
|
1028
|
-
if (!!_b.done) return [3 /*break*/, 4];
|
|
1029
|
-
llmExecutionTools = _b.value;
|
|
1030
|
-
return [4 /*yield*/, llmExecutionTools.checkConfiguration()];
|
|
1031
|
-
case 2:
|
|
1032
|
-
_d.sent();
|
|
1033
|
-
_d.label = 3;
|
|
1034
|
-
case 3:
|
|
1035
|
-
_b = _a.next();
|
|
1036
|
-
return [3 /*break*/, 1];
|
|
1037
|
-
case 4: return [3 /*break*/, 7];
|
|
1038
|
-
case 5:
|
|
1039
|
-
e_1_1 = _d.sent();
|
|
1040
|
-
e_1 = { error: e_1_1 };
|
|
1041
|
-
return [3 /*break*/, 7];
|
|
1042
|
-
case 6:
|
|
1043
|
-
try {
|
|
1044
|
-
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
1045
|
-
}
|
|
1046
|
-
finally { if (e_1) throw e_1.error; }
|
|
1047
|
-
return [7 /*endfinally*/];
|
|
1048
|
-
case 7: return [2 /*return*/];
|
|
1049
|
-
}
|
|
1050
|
-
});
|
|
1051
|
-
});
|
|
1052
|
-
};
|
|
1053
|
-
/**
|
|
1054
|
-
* List all available models that can be used
|
|
1055
|
-
* This lists is a combination of all available models from all execution tools
|
|
1056
|
-
*/
|
|
1057
|
-
MultipleLlmExecutionTools.prototype.listModels = function () {
|
|
1058
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1059
|
-
var availableModels, _a, _b, llmExecutionTools, models, e_2_1;
|
|
1060
|
-
var e_2, _c;
|
|
1061
|
-
return __generator(this, function (_d) {
|
|
1062
|
-
switch (_d.label) {
|
|
1063
|
-
case 0:
|
|
1064
|
-
availableModels = [];
|
|
1065
|
-
_d.label = 1;
|
|
1066
|
-
case 1:
|
|
1067
|
-
_d.trys.push([1, 6, 7, 8]);
|
|
1068
|
-
_a = __values(this.llmExecutionTools), _b = _a.next();
|
|
1069
|
-
_d.label = 2;
|
|
1070
|
-
case 2:
|
|
1071
|
-
if (!!_b.done) return [3 /*break*/, 5];
|
|
1072
|
-
llmExecutionTools = _b.value;
|
|
1073
|
-
return [4 /*yield*/, llmExecutionTools.listModels()];
|
|
1074
|
-
case 3:
|
|
1075
|
-
models = _d.sent();
|
|
1076
|
-
availableModels.push.apply(availableModels, __spreadArray([], __read(models), false));
|
|
1077
|
-
_d.label = 4;
|
|
1078
|
-
case 4:
|
|
1079
|
-
_b = _a.next();
|
|
1080
|
-
return [3 /*break*/, 2];
|
|
1081
|
-
case 5: return [3 /*break*/, 8];
|
|
1082
|
-
case 6:
|
|
1083
|
-
e_2_1 = _d.sent();
|
|
1084
|
-
e_2 = { error: e_2_1 };
|
|
1085
|
-
return [3 /*break*/, 8];
|
|
1086
|
-
case 7:
|
|
1087
|
-
try {
|
|
1088
|
-
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
1089
|
-
}
|
|
1090
|
-
finally { if (e_2) throw e_2.error; }
|
|
1091
|
-
return [7 /*endfinally*/];
|
|
1092
|
-
case 8: return [2 /*return*/, availableModels];
|
|
1093
|
-
}
|
|
1094
|
-
});
|
|
1095
|
-
});
|
|
1096
|
-
};
|
|
1097
|
-
/**
|
|
1098
|
-
* Calls the best available chat model
|
|
1099
|
-
*/
|
|
1100
|
-
MultipleLlmExecutionTools.prototype.callChatModel = function (prompt) {
|
|
1101
|
-
return this.callCommonModel(prompt);
|
|
1102
|
-
};
|
|
1103
|
-
/**
|
|
1104
|
-
* Calls the best available completion model
|
|
1105
|
-
*/
|
|
1106
|
-
MultipleLlmExecutionTools.prototype.callCompletionModel = function (prompt) {
|
|
1107
|
-
return this.callCommonModel(prompt);
|
|
1108
|
-
};
|
|
1109
|
-
/**
|
|
1110
|
-
* Calls the best available embedding model
|
|
1111
|
-
*/
|
|
1112
|
-
MultipleLlmExecutionTools.prototype.callEmbeddingModel = function (prompt) {
|
|
1113
|
-
return this.callCommonModel(prompt);
|
|
1114
|
-
};
|
|
1115
|
-
// <- Note: [🤖]
|
|
1116
|
-
/**
|
|
1117
|
-
* Calls the best available model
|
|
1118
|
-
*
|
|
1119
|
-
* Note: This should be private or protected but is public to be usable with duck typing
|
|
1120
|
-
*/
|
|
1121
|
-
MultipleLlmExecutionTools.prototype.callCommonModel = function (prompt) {
|
|
1122
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1123
|
-
var errors, _a, _b, llmExecutionTools, _c, error_1, e_3_1;
|
|
1124
|
-
var e_3, _d;
|
|
1125
|
-
var _this = this;
|
|
1126
|
-
return __generator(this, function (_e) {
|
|
1127
|
-
switch (_e.label) {
|
|
1128
|
-
case 0:
|
|
1129
|
-
errors = [];
|
|
1130
|
-
_e.label = 1;
|
|
1131
|
-
case 1:
|
|
1132
|
-
_e.trys.push([1, 15, 16, 17]);
|
|
1133
|
-
_a = __values(this.llmExecutionTools), _b = _a.next();
|
|
1134
|
-
_e.label = 2;
|
|
1135
|
-
case 2:
|
|
1136
|
-
if (!!_b.done) return [3 /*break*/, 14];
|
|
1137
|
-
llmExecutionTools = _b.value;
|
|
1138
|
-
_e.label = 3;
|
|
1139
|
-
case 3:
|
|
1140
|
-
_e.trys.push([3, 12, , 13]);
|
|
1141
|
-
_c = prompt.modelRequirements.modelVariant;
|
|
1142
|
-
switch (_c) {
|
|
1143
|
-
case 'CHAT': return [3 /*break*/, 4];
|
|
1144
|
-
case 'COMPLETION': return [3 /*break*/, 6];
|
|
1145
|
-
case 'EMBEDDING': return [3 /*break*/, 8];
|
|
1146
|
-
}
|
|
1147
|
-
return [3 /*break*/, 10];
|
|
1148
|
-
case 4:
|
|
1149
|
-
if (llmExecutionTools.callChatModel === undefined) {
|
|
1150
|
-
return [3 /*break*/, 13];
|
|
1151
|
-
}
|
|
1152
|
-
return [4 /*yield*/, llmExecutionTools.callChatModel(prompt)];
|
|
1153
|
-
case 5: return [2 /*return*/, _e.sent()];
|
|
1154
|
-
case 6:
|
|
1155
|
-
if (llmExecutionTools.callCompletionModel === undefined) {
|
|
1156
|
-
return [3 /*break*/, 13];
|
|
1157
|
-
}
|
|
1158
|
-
return [4 /*yield*/, llmExecutionTools.callCompletionModel(prompt)];
|
|
1159
|
-
case 7: return [2 /*return*/, _e.sent()];
|
|
1160
|
-
case 8:
|
|
1161
|
-
if (llmExecutionTools.callEmbeddingModel === undefined) {
|
|
1162
|
-
return [3 /*break*/, 13];
|
|
1163
|
-
}
|
|
1164
|
-
return [4 /*yield*/, llmExecutionTools.callEmbeddingModel(prompt)];
|
|
1165
|
-
case 9: return [2 /*return*/, _e.sent()];
|
|
1166
|
-
case 10: throw new UnexpectedError("Unknown model variant \"".concat(prompt.modelRequirements.modelVariant, "\""));
|
|
1167
|
-
case 11: return [3 /*break*/, 13];
|
|
1168
|
-
case 12:
|
|
1169
|
-
error_1 = _e.sent();
|
|
1170
|
-
if (!(error_1 instanceof Error) || error_1 instanceof UnexpectedError) {
|
|
1171
|
-
throw error_1;
|
|
1172
|
-
}
|
|
1173
|
-
errors.push(error_1);
|
|
1174
|
-
return [3 /*break*/, 13];
|
|
1175
|
-
case 13:
|
|
1176
|
-
_b = _a.next();
|
|
1177
|
-
return [3 /*break*/, 2];
|
|
1178
|
-
case 14: return [3 /*break*/, 17];
|
|
1179
|
-
case 15:
|
|
1180
|
-
e_3_1 = _e.sent();
|
|
1181
|
-
e_3 = { error: e_3_1 };
|
|
1182
|
-
return [3 /*break*/, 17];
|
|
1183
|
-
case 16:
|
|
1184
|
-
try {
|
|
1185
|
-
if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
|
|
1186
|
-
}
|
|
1187
|
-
finally { if (e_3) throw e_3.error; }
|
|
1188
|
-
return [7 /*endfinally*/];
|
|
1189
|
-
case 17:
|
|
1190
|
-
if (errors.length === 1) {
|
|
1191
|
-
throw errors[0];
|
|
1192
|
-
}
|
|
1193
|
-
else if (errors.length > 1) {
|
|
1194
|
-
throw new PipelineExecutionError(
|
|
1195
|
-
// TODO: Tell which execution tools failed like
|
|
1196
|
-
// 1) OpenAI throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
1197
|
-
// 2) AnthropicClaude throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
1198
|
-
// 3) ...
|
|
1199
|
-
spaceTrim__default["default"](function (block) { return "\n All execution tools failed:\n\n ".concat(block(errors
|
|
1200
|
-
.map(function (error, i) { return "".concat(i + 1, ") **").concat(error.name || 'Error', ":** ").concat(error.message); })
|
|
1201
|
-
.join('\n')), "\n\n "); }));
|
|
1202
|
-
}
|
|
1203
|
-
else if (this.llmExecutionTools.length === 0) {
|
|
1204
|
-
throw new PipelineExecutionError("You have not provided any `LlmExecutionTools`");
|
|
1205
|
-
}
|
|
1206
|
-
else {
|
|
1207
|
-
throw new PipelineExecutionError(spaceTrim__default["default"](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 "); }));
|
|
1208
|
-
}
|
|
1209
|
-
}
|
|
1210
|
-
});
|
|
885
|
+
function exportJson(options) {
|
|
886
|
+
var name = options.name, value = options.value, order = options.order, message = options.message;
|
|
887
|
+
checkSerializableAsJson({ name: name, value: value, message: message });
|
|
888
|
+
var orderedValue =
|
|
889
|
+
// TODO: Fix error "Type instantiation is excessively deep and possibly infinite."
|
|
890
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
891
|
+
// @ts-ignore
|
|
892
|
+
order === undefined
|
|
893
|
+
? deepClone(value)
|
|
894
|
+
: orderJson({
|
|
895
|
+
value: value,
|
|
896
|
+
// <- Note: checkSerializableAsJson asserts that the value is serializable as JSON
|
|
897
|
+
order: order,
|
|
1211
898
|
});
|
|
1212
|
-
|
|
1213
|
-
return
|
|
1214
|
-
}
|
|
899
|
+
$deepFreeze(orderedValue);
|
|
900
|
+
return orderedValue;
|
|
901
|
+
}
|
|
1215
902
|
/**
|
|
1216
|
-
* TODO: [🧠]
|
|
1217
|
-
* 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
|
|
1218
|
-
* Look how `countTotalUsage` (and `cacheLlmTools`) implements it
|
|
903
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
1219
904
|
*/
|
|
1220
905
|
|
|
1221
906
|
/**
|
|
1222
|
-
*
|
|
1223
|
-
*
|
|
1224
|
-
* @returns {LlmExecutionTools} Single wrapper for multiple LlmExecutionTools
|
|
1225
|
-
*
|
|
1226
|
-
* 0) If there is no LlmExecutionTools, it warns and returns valid but empty LlmExecutionTools
|
|
1227
|
-
* 1) If there is only one LlmExecutionTools, it returns it wrapped in a proxy object
|
|
1228
|
-
* 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.
|
|
1229
|
-
* 3) When all LlmExecutionTools fail, it throws an error with a list of all errors merged into one
|
|
1230
|
-
*
|
|
1231
|
-
*
|
|
1232
|
-
* Tip: You don't have to use this function directly, just pass an array of LlmExecutionTools to the `ExecutionTools`
|
|
907
|
+
* Order of keys in the pipeline JSON
|
|
1233
908
|
*
|
|
1234
909
|
* @public exported from `@promptbook/core`
|
|
1235
910
|
*/
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
911
|
+
var ORDER_OF_PIPELINE_JSON = [
|
|
912
|
+
// Note: [🍙] In this order will be pipeline serialized
|
|
913
|
+
'title',
|
|
914
|
+
'pipelineUrl',
|
|
915
|
+
'bookVersion',
|
|
916
|
+
'description',
|
|
917
|
+
'formfactorName',
|
|
918
|
+
'parameters',
|
|
919
|
+
'tasks',
|
|
920
|
+
'personas',
|
|
921
|
+
'preparations',
|
|
922
|
+
'knowledgeSources',
|
|
923
|
+
'knowledgePieces',
|
|
924
|
+
'sources', // <- TODO: [🧠] Where should the `sources` be
|
|
925
|
+
];
|
|
926
|
+
/**
|
|
927
|
+
* Nonce which is used for replacing things in strings
|
|
928
|
+
*
|
|
929
|
+
* @private within the repository
|
|
930
|
+
*/
|
|
931
|
+
var REPLACING_NONCE = 'u$k42k%!V2zo34w7Fu#@QUHYPW';
|
|
932
|
+
/**
|
|
933
|
+
* @@@
|
|
934
|
+
*
|
|
935
|
+
* @private within the repository
|
|
936
|
+
*/
|
|
937
|
+
var RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
|
|
938
|
+
/**
|
|
939
|
+
* @@@
|
|
940
|
+
*
|
|
941
|
+
* @private within the repository
|
|
942
|
+
*/
|
|
943
|
+
var RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;
|
|
944
|
+
/**
|
|
945
|
+
* The names of the parameters that are reserved for special purposes
|
|
946
|
+
*
|
|
947
|
+
* @public exported from `@promptbook/core`
|
|
948
|
+
*/
|
|
949
|
+
var RESERVED_PARAMETER_NAMES = exportJson({
|
|
950
|
+
name: 'RESERVED_PARAMETER_NAMES',
|
|
951
|
+
message: "The names of the parameters that are reserved for special purposes",
|
|
952
|
+
value: [
|
|
953
|
+
'content',
|
|
954
|
+
'context',
|
|
955
|
+
'knowledge',
|
|
956
|
+
'examples',
|
|
957
|
+
'modelName',
|
|
958
|
+
'currentDate',
|
|
959
|
+
// <- TODO: list here all command names
|
|
960
|
+
// <- TODO: Add more like 'date', 'modelName',...
|
|
961
|
+
// <- TODO: Add [emoji] + instructions ACRY when adding new reserved parameter
|
|
962
|
+
],
|
|
963
|
+
});
|
|
964
|
+
/**
|
|
965
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
966
|
+
*/
|
|
1254
967
|
|
|
1255
|
-
|
|
968
|
+
/**
|
|
969
|
+
* This error indicates that the promptbook object has valid syntax (=can be parsed) but contains logical errors (like circular dependencies)
|
|
970
|
+
*
|
|
971
|
+
* @public exported from `@promptbook/core`
|
|
972
|
+
*/
|
|
973
|
+
var PipelineLogicError = /** @class */ (function (_super) {
|
|
974
|
+
__extends(PipelineLogicError, _super);
|
|
975
|
+
function PipelineLogicError(message) {
|
|
976
|
+
var _this = _super.call(this, message) || this;
|
|
977
|
+
_this.name = 'PipelineLogicError';
|
|
978
|
+
Object.setPrototypeOf(_this, PipelineLogicError.prototype);
|
|
979
|
+
return _this;
|
|
980
|
+
}
|
|
981
|
+
return PipelineLogicError;
|
|
982
|
+
}(Error));
|
|
1256
983
|
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
984
|
+
/**
|
|
985
|
+
* Tests if given string is valid semantic version
|
|
986
|
+
*
|
|
987
|
+
* Note: There are two simmilar functions:
|
|
988
|
+
* - `isValidSemanticVersion` which tests any semantic version
|
|
989
|
+
* - `isValidPromptbookVersion` *(this one)* which tests just Promptbook versions
|
|
990
|
+
*
|
|
991
|
+
* @public exported from `@promptbook/utils`
|
|
992
|
+
*/
|
|
993
|
+
function isValidSemanticVersion(version) {
|
|
994
|
+
if (typeof version !== 'string') {
|
|
995
|
+
return false;
|
|
1265
996
|
}
|
|
1266
|
-
|
|
997
|
+
if (version.startsWith('0.0.0')) {
|
|
998
|
+
return false;
|
|
999
|
+
}
|
|
1000
|
+
return /^\d+\.\d+\.\d+(-\d+)?$/i.test(version);
|
|
1267
1001
|
}
|
|
1002
|
+
|
|
1268
1003
|
/**
|
|
1269
|
-
*
|
|
1004
|
+
* Tests if given string is valid promptbook version
|
|
1005
|
+
* It looks into list of known promptbook versions.
|
|
1006
|
+
*
|
|
1007
|
+
* @see https://www.npmjs.com/package/promptbook?activeTab=versions
|
|
1008
|
+
* 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.
|
|
1009
|
+
* Note: There are two simmilar functions:
|
|
1010
|
+
* - `isValidSemanticVersion` which tests any semantic version
|
|
1011
|
+
* - `isValidPromptbookVersion` *(this one)* which tests just Promptbook versions
|
|
1012
|
+
*
|
|
1013
|
+
* @public exported from `@promptbook/utils`
|
|
1270
1014
|
*/
|
|
1271
|
-
|
|
1272
|
-
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"}];
|
|
1015
|
+
function isValidPromptbookVersion(version) {
|
|
1016
|
+
if (!isValidSemanticVersion(version)) {
|
|
1017
|
+
return false;
|
|
1018
|
+
}
|
|
1019
|
+
if ( /* version === '1.0.0' || */version === '2.0.0' || version === '3.0.0') {
|
|
1020
|
+
return false;
|
|
1021
|
+
}
|
|
1022
|
+
// <- TODO: [main] !!3 Check isValidPromptbookVersion against PROMPTBOOK_ENGINE_VERSIONS
|
|
1023
|
+
return true;
|
|
1024
|
+
}
|
|
1273
1025
|
|
|
1274
1026
|
/**
|
|
1275
|
-
*
|
|
1027
|
+
* Checks if an URL is reserved for private networks or localhost.
|
|
1276
1028
|
*
|
|
1277
|
-
*
|
|
1278
|
-
*
|
|
1279
|
-
*
|
|
1029
|
+
* Note: There are two simmilar functions:
|
|
1030
|
+
* - `isUrlOnPrivateNetwork` which tests full URL
|
|
1031
|
+
* - `isHostnameOnPrivateNetwork` *(this one)* which tests just hostname
|
|
1032
|
+
*
|
|
1033
|
+
* @public exported from `@promptbook/utils`
|
|
1280
1034
|
*/
|
|
1281
|
-
function
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
trailingComma: 'all',
|
|
1291
|
-
arrowParens: 'always',
|
|
1292
|
-
printWidth: 120,
|
|
1293
|
-
htmlWhitespaceSensitivity: 'ignore',
|
|
1294
|
-
jsxBracketSameLine: false,
|
|
1295
|
-
bracketSpacing: true,
|
|
1296
|
-
});
|
|
1035
|
+
function isHostnameOnPrivateNetwork(hostname) {
|
|
1036
|
+
if (hostname === 'example.com' ||
|
|
1037
|
+
hostname === 'localhost' ||
|
|
1038
|
+
hostname.endsWith('.localhost') ||
|
|
1039
|
+
hostname.endsWith('.local') ||
|
|
1040
|
+
hostname.endsWith('.test') ||
|
|
1041
|
+
hostname === '127.0.0.1' ||
|
|
1042
|
+
hostname === '::1') {
|
|
1043
|
+
return true;
|
|
1297
1044
|
}
|
|
1298
|
-
|
|
1299
|
-
//
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1045
|
+
if (hostname.includes(':')) {
|
|
1046
|
+
// IPv6
|
|
1047
|
+
var ipParts = hostname.split(':');
|
|
1048
|
+
return ipParts[0] === 'fc00' || ipParts[0] === 'fd00' || ipParts[0] === 'fe80';
|
|
1049
|
+
}
|
|
1050
|
+
else {
|
|
1051
|
+
// IPv4
|
|
1052
|
+
var ipParts = hostname.split('.').map(function (part) { return Number.parseInt(part, 10); });
|
|
1053
|
+
return (ipParts[0] === 10 ||
|
|
1054
|
+
(ipParts[0] === 172 && ipParts[1] >= 16 && ipParts[1] <= 31) ||
|
|
1055
|
+
(ipParts[0] === 192 && ipParts[1] === 168));
|
|
1305
1056
|
}
|
|
1306
1057
|
}
|
|
1307
1058
|
|
|
1308
1059
|
/**
|
|
1309
|
-
*
|
|
1060
|
+
* Checks if an IP address or hostname is reserved for private networks or localhost.
|
|
1061
|
+
*
|
|
1062
|
+
* Note: There are two simmilar functions:
|
|
1063
|
+
* - `isUrlOnPrivateNetwork` *(this one)* which tests full URL
|
|
1064
|
+
* - `isHostnameOnPrivateNetwork` which tests just hostname
|
|
1310
1065
|
*
|
|
1066
|
+
* @param {string} ipAddress - The IP address to check.
|
|
1067
|
+
* @returns {boolean} Returns true if the IP address is reserved for private networks or localhost, otherwise false.
|
|
1311
1068
|
* @public exported from `@promptbook/utils`
|
|
1312
1069
|
*/
|
|
1313
|
-
function
|
|
1314
|
-
|
|
1070
|
+
function isUrlOnPrivateNetwork(url) {
|
|
1071
|
+
if (typeof url === 'string') {
|
|
1072
|
+
url = new URL(url);
|
|
1073
|
+
}
|
|
1074
|
+
return isHostnameOnPrivateNetwork(url.hostname);
|
|
1315
1075
|
}
|
|
1316
1076
|
|
|
1317
1077
|
/**
|
|
1318
|
-
*
|
|
1078
|
+
* Tests if given string is valid URL.
|
|
1319
1079
|
*
|
|
1320
|
-
*
|
|
1321
|
-
*
|
|
1322
|
-
*
|
|
1323
|
-
*
|
|
1080
|
+
* Note: Dataurl are considered perfectly valid.
|
|
1081
|
+
* Note: There are two simmilar functions:
|
|
1082
|
+
* - `isValidUrl` which tests any URL
|
|
1083
|
+
* - `isValidPipelineUrl` *(this one)* which tests just promptbook URL
|
|
1084
|
+
*
|
|
1085
|
+
* @public exported from `@promptbook/utils`
|
|
1324
1086
|
*/
|
|
1325
|
-
function
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
var pipelineString = "# ".concat(title);
|
|
1329
|
-
if (description) {
|
|
1330
|
-
pipelineString += '\n\n';
|
|
1331
|
-
pipelineString += description;
|
|
1332
|
-
}
|
|
1333
|
-
var commands = [];
|
|
1334
|
-
if (pipelineUrl) {
|
|
1335
|
-
commands.push("PIPELINE URL ".concat(pipelineUrl));
|
|
1336
|
-
}
|
|
1337
|
-
if (bookVersion !== "undefined") {
|
|
1338
|
-
commands.push("BOOK VERSION ".concat(bookVersion));
|
|
1087
|
+
function isValidUrl(url) {
|
|
1088
|
+
if (typeof url !== 'string') {
|
|
1089
|
+
return false;
|
|
1339
1090
|
}
|
|
1340
|
-
// TODO: [main] !!!!! This increases size of the bundle and is probbably not necessary
|
|
1341
|
-
pipelineString = prettifyMarkdown(pipelineString);
|
|
1342
1091
|
try {
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
return isInput;
|
|
1346
|
-
})), _h = _g.next(); !_h.done; _h = _g.next()) {
|
|
1347
|
-
var parameter = _h.value;
|
|
1348
|
-
commands.push("INPUT PARAMETER ".concat(taskParameterJsonToString(parameter)));
|
|
1092
|
+
if (url.startsWith('blob:')) {
|
|
1093
|
+
url = url.replace(/^blob:/, '');
|
|
1349
1094
|
}
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
try {
|
|
1354
|
-
if (_h && !_h.done && (_a = _g.return)) _a.call(_g);
|
|
1095
|
+
var urlObject = new URL(url /* because fail is handled */);
|
|
1096
|
+
if (!['http:', 'https:', 'data:'].includes(urlObject.protocol)) {
|
|
1097
|
+
return false;
|
|
1355
1098
|
}
|
|
1356
|
-
|
|
1099
|
+
return true;
|
|
1357
1100
|
}
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
var isOutput = _a.isOutput;
|
|
1361
|
-
return isOutput;
|
|
1362
|
-
})), _k = _j.next(); !_k.done; _k = _j.next()) {
|
|
1363
|
-
var parameter = _k.value;
|
|
1364
|
-
commands.push("OUTPUT PARAMETER ".concat(taskParameterJsonToString(parameter)));
|
|
1365
|
-
}
|
|
1101
|
+
catch (error) {
|
|
1102
|
+
return false;
|
|
1366
1103
|
}
|
|
1367
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
1368
|
-
finally {
|
|
1369
|
-
try {
|
|
1370
|
-
if (_k && !_k.done && (_b = _j.return)) _b.call(_j);
|
|
1371
|
-
}
|
|
1372
|
-
finally { if (e_2) throw e_2.error; }
|
|
1373
|
-
}
|
|
1374
|
-
pipelineString += '\n\n';
|
|
1375
|
-
pipelineString += commands.map(function (command) { return "- ".concat(command); }).join('\n');
|
|
1376
|
-
try {
|
|
1377
|
-
for (var tasks_1 = __values(tasks), tasks_1_1 = tasks_1.next(); !tasks_1_1.done; tasks_1_1 = tasks_1.next()) {
|
|
1378
|
-
var task = tasks_1_1.value;
|
|
1379
|
-
var
|
|
1380
|
-
/* Note: Not using:> name, */
|
|
1381
|
-
title_1 = task.title, description_1 = task.description,
|
|
1382
|
-
/* Note: dependentParameterNames, */
|
|
1383
|
-
jokers = task.jokerParameterNames, taskType = task.taskType, content = task.content, postprocessing = task.postprocessingFunctionNames, expectations = task.expectations, format = task.format, resultingParameterName = task.resultingParameterName;
|
|
1384
|
-
pipelineString += '\n\n';
|
|
1385
|
-
pipelineString += "## ".concat(title_1);
|
|
1386
|
-
if (description_1) {
|
|
1387
|
-
pipelineString += '\n\n';
|
|
1388
|
-
pipelineString += description_1;
|
|
1389
|
-
}
|
|
1390
|
-
var commands_1 = [];
|
|
1391
|
-
var contentLanguage = 'text';
|
|
1392
|
-
if (taskType === 'PROMPT_TASK') {
|
|
1393
|
-
var modelRequirements = task.modelRequirements;
|
|
1394
|
-
var _l = modelRequirements || {}, modelName = _l.modelName, modelVariant = _l.modelVariant;
|
|
1395
|
-
// Note: Do nothing, it is default
|
|
1396
|
-
// commands.push(`PROMPT`);
|
|
1397
|
-
if (modelVariant) {
|
|
1398
|
-
commands_1.push("MODEL VARIANT ".concat(capitalize(modelVariant)));
|
|
1399
|
-
}
|
|
1400
|
-
if (modelName) {
|
|
1401
|
-
commands_1.push("MODEL NAME `".concat(modelName, "`"));
|
|
1402
|
-
}
|
|
1403
|
-
}
|
|
1404
|
-
else if (taskType === 'SIMPLE_TASK') {
|
|
1405
|
-
commands_1.push("SIMPLE TEMPLATE");
|
|
1406
|
-
// Note: Nothing special here
|
|
1407
|
-
}
|
|
1408
|
-
else if (taskType === 'SCRIPT_TASK') {
|
|
1409
|
-
commands_1.push("SCRIPT");
|
|
1410
|
-
if (task.contentLanguage) {
|
|
1411
|
-
contentLanguage = task.contentLanguage;
|
|
1412
|
-
}
|
|
1413
|
-
else {
|
|
1414
|
-
contentLanguage = '';
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1417
|
-
else if (taskType === 'DIALOG_TASK') {
|
|
1418
|
-
commands_1.push("DIALOG");
|
|
1419
|
-
// Note: Nothing special here
|
|
1420
|
-
} // <- }else if([🅱]
|
|
1421
|
-
if (jokers) {
|
|
1422
|
-
try {
|
|
1423
|
-
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()) {
|
|
1424
|
-
var joker = jokers_1_1.value;
|
|
1425
|
-
commands_1.push("JOKER {".concat(joker, "}"));
|
|
1426
|
-
}
|
|
1427
|
-
}
|
|
1428
|
-
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
1429
|
-
finally {
|
|
1430
|
-
try {
|
|
1431
|
-
if (jokers_1_1 && !jokers_1_1.done && (_d = jokers_1.return)) _d.call(jokers_1);
|
|
1432
|
-
}
|
|
1433
|
-
finally { if (e_4) throw e_4.error; }
|
|
1434
|
-
}
|
|
1435
|
-
} /* not else */
|
|
1436
|
-
if (postprocessing) {
|
|
1437
|
-
try {
|
|
1438
|
-
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()) {
|
|
1439
|
-
var postprocessingFunctionName = postprocessing_1_1.value;
|
|
1440
|
-
commands_1.push("POSTPROCESSING `".concat(postprocessingFunctionName, "`"));
|
|
1441
|
-
}
|
|
1442
|
-
}
|
|
1443
|
-
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
1444
|
-
finally {
|
|
1445
|
-
try {
|
|
1446
|
-
if (postprocessing_1_1 && !postprocessing_1_1.done && (_e = postprocessing_1.return)) _e.call(postprocessing_1);
|
|
1447
|
-
}
|
|
1448
|
-
finally { if (e_5) throw e_5.error; }
|
|
1449
|
-
}
|
|
1450
|
-
} /* not else */
|
|
1451
|
-
if (expectations) {
|
|
1452
|
-
try {
|
|
1453
|
-
for (var _m = (e_6 = void 0, __values(Object.entries(expectations))), _o = _m.next(); !_o.done; _o = _m.next()) {
|
|
1454
|
-
var _p = __read(_o.value, 2), unit = _p[0], _q = _p[1], min = _q.min, max = _q.max;
|
|
1455
|
-
if (min === max) {
|
|
1456
|
-
commands_1.push("EXPECT EXACTLY ".concat(min, " ").concat(capitalize(unit + (min > 1 ? 's' : ''))));
|
|
1457
|
-
}
|
|
1458
|
-
else {
|
|
1459
|
-
if (min !== undefined) {
|
|
1460
|
-
commands_1.push("EXPECT MIN ".concat(min, " ").concat(capitalize(unit + (min > 1 ? 's' : ''))));
|
|
1461
|
-
} /* not else */
|
|
1462
|
-
if (max !== undefined) {
|
|
1463
|
-
commands_1.push("EXPECT MAX ".concat(max, " ").concat(capitalize(unit + (max > 1 ? 's' : ''))));
|
|
1464
|
-
}
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
1467
|
-
}
|
|
1468
|
-
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
1469
|
-
finally {
|
|
1470
|
-
try {
|
|
1471
|
-
if (_o && !_o.done && (_f = _m.return)) _f.call(_m);
|
|
1472
|
-
}
|
|
1473
|
-
finally { if (e_6) throw e_6.error; }
|
|
1474
|
-
}
|
|
1475
|
-
} /* not else */
|
|
1476
|
-
if (format) {
|
|
1477
|
-
if (format === 'JSON') {
|
|
1478
|
-
// TODO: @deprecated remove
|
|
1479
|
-
commands_1.push("FORMAT JSON");
|
|
1480
|
-
}
|
|
1481
|
-
} /* not else */
|
|
1482
|
-
pipelineString += '\n\n';
|
|
1483
|
-
pipelineString += commands_1.map(function (command) { return "- ".concat(command); }).join('\n');
|
|
1484
|
-
pipelineString += '\n\n';
|
|
1485
|
-
pipelineString += '```' + contentLanguage;
|
|
1486
|
-
pipelineString += '\n';
|
|
1487
|
-
pipelineString += spaceTrim__default["default"](content);
|
|
1488
|
-
// <- TODO: [main] !!! Escape
|
|
1489
|
-
// <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
|
|
1490
|
-
pipelineString += '\n';
|
|
1491
|
-
pipelineString += '```';
|
|
1492
|
-
pipelineString += '\n\n';
|
|
1493
|
-
pipelineString += "`-> {".concat(resultingParameterName, "}`"); // <- TODO: [main] !!! If the parameter here has description, add it and use taskParameterJsonToString
|
|
1494
|
-
}
|
|
1495
|
-
}
|
|
1496
|
-
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
1497
|
-
finally {
|
|
1498
|
-
try {
|
|
1499
|
-
if (tasks_1_1 && !tasks_1_1.done && (_c = tasks_1.return)) _c.call(tasks_1);
|
|
1500
|
-
}
|
|
1501
|
-
finally { if (e_3) throw e_3.error; }
|
|
1502
|
-
}
|
|
1503
|
-
return pipelineString;
|
|
1504
|
-
}
|
|
1505
|
-
/**
|
|
1506
|
-
* @private internal utility of `pipelineJsonToString`
|
|
1507
|
-
*/
|
|
1508
|
-
function taskParameterJsonToString(taskParameterJson) {
|
|
1509
|
-
var name = taskParameterJson.name, description = taskParameterJson.description;
|
|
1510
|
-
var parameterString = "{".concat(name, "}");
|
|
1511
|
-
if (description) {
|
|
1512
|
-
parameterString = "".concat(parameterString, " ").concat(description);
|
|
1513
|
-
}
|
|
1514
|
-
return parameterString;
|
|
1515
1104
|
}
|
|
1516
|
-
/**
|
|
1517
|
-
* TODO: [🛋] Implement new features and commands into `pipelineJsonToString` + `taskParameterJsonToString` , use `stringifyCommand`
|
|
1518
|
-
* TODO: [🧠] Is there a way to auto-detect missing features in pipelineJsonToString
|
|
1519
|
-
* TODO: [🏛] Maybe make some markdown builder
|
|
1520
|
-
* TODO: [🏛] Escape all
|
|
1521
|
-
* TODO: [🧠] Should be in generated .book.md file GENERATOR_WARNING
|
|
1522
|
-
*/
|
|
1523
|
-
|
|
1524
|
-
/**
|
|
1525
|
-
* This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
|
|
1526
|
-
*
|
|
1527
|
-
* @public exported from `@promptbook/core`
|
|
1528
|
-
*/
|
|
1529
|
-
var ParseError = /** @class */ (function (_super) {
|
|
1530
|
-
__extends(ParseError, _super);
|
|
1531
|
-
function ParseError(message) {
|
|
1532
|
-
var _this = _super.call(this, message) || this;
|
|
1533
|
-
_this.name = 'ParseError';
|
|
1534
|
-
Object.setPrototypeOf(_this, ParseError.prototype);
|
|
1535
|
-
return _this;
|
|
1536
|
-
}
|
|
1537
|
-
return ParseError;
|
|
1538
|
-
}(Error));
|
|
1539
|
-
/**
|
|
1540
|
-
* TODO: Maybe split `ParseError` and `ApplyError`
|
|
1541
|
-
*/
|
|
1542
|
-
|
|
1543
|
-
/**
|
|
1544
|
-
* This error indicates that the promptbook object has valid syntax (=can be parsed) but contains logical errors (like circular dependencies)
|
|
1545
|
-
*
|
|
1546
|
-
* @public exported from `@promptbook/core`
|
|
1547
|
-
*/
|
|
1548
|
-
var PipelineLogicError = /** @class */ (function (_super) {
|
|
1549
|
-
__extends(PipelineLogicError, _super);
|
|
1550
|
-
function PipelineLogicError(message) {
|
|
1551
|
-
var _this = _super.call(this, message) || this;
|
|
1552
|
-
_this.name = 'PipelineLogicError';
|
|
1553
|
-
Object.setPrototypeOf(_this, PipelineLogicError.prototype);
|
|
1554
|
-
return _this;
|
|
1555
|
-
}
|
|
1556
|
-
return PipelineLogicError;
|
|
1557
|
-
}(Error));
|
|
1558
1105
|
|
|
1559
1106
|
/**
|
|
1560
|
-
* Tests if given string is valid
|
|
1107
|
+
* Tests if given string is valid pipeline URL URL.
|
|
1561
1108
|
*
|
|
1562
1109
|
* Note: There are two simmilar functions:
|
|
1563
|
-
* - `
|
|
1564
|
-
* - `
|
|
1110
|
+
* - `isValidUrl` which tests any URL
|
|
1111
|
+
* - `isValidPipelineUrl` *(this one)* which tests just pipeline URL
|
|
1565
1112
|
*
|
|
1566
1113
|
* @public exported from `@promptbook/utils`
|
|
1567
1114
|
*/
|
|
1568
|
-
function
|
|
1569
|
-
if (
|
|
1115
|
+
function isValidPipelineUrl(url) {
|
|
1116
|
+
if (!isValidUrl(url)) {
|
|
1570
1117
|
return false;
|
|
1571
1118
|
}
|
|
1572
|
-
if (
|
|
1119
|
+
if (!url.startsWith('https://')) {
|
|
1573
1120
|
return false;
|
|
1574
1121
|
}
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
/**
|
|
1579
|
-
* Tests if given string is valid promptbook version
|
|
1580
|
-
* It looks into list of known promptbook versions.
|
|
1581
|
-
*
|
|
1582
|
-
* @see https://www.npmjs.com/package/promptbook?activeTab=versions
|
|
1583
|
-
* 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.
|
|
1584
|
-
* Note: There are two simmilar functions:
|
|
1585
|
-
* - `isValidSemanticVersion` which tests any semantic version
|
|
1586
|
-
* - `isValidPromptbookVersion` *(this one)* which tests just Promptbook versions
|
|
1587
|
-
*
|
|
1588
|
-
* @public exported from `@promptbook/utils`
|
|
1589
|
-
*/
|
|
1590
|
-
function isValidPromptbookVersion(version) {
|
|
1591
|
-
if (!isValidSemanticVersion(version)) {
|
|
1122
|
+
if (url.includes('#')) {
|
|
1123
|
+
// TODO: [🐠]
|
|
1592
1124
|
return false;
|
|
1593
1125
|
}
|
|
1594
|
-
if (
|
|
1126
|
+
if (isUrlOnPrivateNetwork(url)) {
|
|
1595
1127
|
return false;
|
|
1596
1128
|
}
|
|
1597
|
-
// <- TODO: [main] !!! Check isValidPromptbookVersion against PROMPTBOOK_ENGINE_VERSIONS
|
|
1598
1129
|
return true;
|
|
1599
1130
|
}
|
|
1131
|
+
/**
|
|
1132
|
+
* TODO: [🐠] Maybe more info why the URL is invalid
|
|
1133
|
+
*/
|
|
1600
1134
|
|
|
1601
1135
|
/**
|
|
1602
|
-
*
|
|
1136
|
+
* Validates PipelineJson if it is logically valid
|
|
1603
1137
|
*
|
|
1604
|
-
*
|
|
1605
|
-
* -
|
|
1606
|
-
* - `isHostnameOnPrivateNetwork` *(this one)* which tests just hostname
|
|
1138
|
+
* It checks:
|
|
1139
|
+
* - if it has correct parameters dependency
|
|
1607
1140
|
*
|
|
1608
|
-
*
|
|
1141
|
+
* It does NOT check:
|
|
1142
|
+
* - if it is valid json
|
|
1143
|
+
* - if it is meaningful
|
|
1144
|
+
*
|
|
1145
|
+
* @param pipeline valid or invalid PipelineJson
|
|
1146
|
+
* @returns the same pipeline if it is logically valid
|
|
1147
|
+
* @throws {PipelineLogicError} on logical error in the pipeline
|
|
1148
|
+
* @public exported from `@promptbook/core`
|
|
1609
1149
|
*/
|
|
1610
|
-
function
|
|
1611
|
-
if (
|
|
1612
|
-
|
|
1613
|
-
hostname.endsWith('.localhost') ||
|
|
1614
|
-
hostname.endsWith('.local') ||
|
|
1615
|
-
hostname.endsWith('.test') ||
|
|
1616
|
-
hostname === '127.0.0.1' ||
|
|
1617
|
-
hostname === '::1') {
|
|
1618
|
-
return true;
|
|
1619
|
-
}
|
|
1620
|
-
if (hostname.includes(':')) {
|
|
1621
|
-
// IPv6
|
|
1622
|
-
var ipParts = hostname.split(':');
|
|
1623
|
-
return ipParts[0] === 'fc00' || ipParts[0] === 'fd00' || ipParts[0] === 'fe80';
|
|
1624
|
-
}
|
|
1625
|
-
else {
|
|
1626
|
-
// IPv4
|
|
1627
|
-
var ipParts = hostname.split('.').map(function (part) { return Number.parseInt(part, 10); });
|
|
1628
|
-
return (ipParts[0] === 10 ||
|
|
1629
|
-
(ipParts[0] === 172 && ipParts[1] >= 16 && ipParts[1] <= 31) ||
|
|
1630
|
-
(ipParts[0] === 192 && ipParts[1] === 168));
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
|
|
1634
|
-
/**
|
|
1635
|
-
* Checks if an IP address or hostname is reserved for private networks or localhost.
|
|
1636
|
-
*
|
|
1637
|
-
* Note: There are two simmilar functions:
|
|
1638
|
-
* - `isUrlOnPrivateNetwork` *(this one)* which tests full URL
|
|
1639
|
-
* - `isHostnameOnPrivateNetwork` which tests just hostname
|
|
1640
|
-
*
|
|
1641
|
-
* @param {string} ipAddress - The IP address to check.
|
|
1642
|
-
* @returns {boolean} Returns true if the IP address is reserved for private networks or localhost, otherwise false.
|
|
1643
|
-
* @public exported from `@promptbook/utils`
|
|
1644
|
-
*/
|
|
1645
|
-
function isUrlOnPrivateNetwork(url) {
|
|
1646
|
-
if (typeof url === 'string') {
|
|
1647
|
-
url = new URL(url);
|
|
1648
|
-
}
|
|
1649
|
-
return isHostnameOnPrivateNetwork(url.hostname);
|
|
1650
|
-
}
|
|
1651
|
-
|
|
1652
|
-
/**
|
|
1653
|
-
* Tests if given string is valid URL.
|
|
1654
|
-
*
|
|
1655
|
-
* Note: Dataurl are considered perfectly valid.
|
|
1656
|
-
* Note: There are two simmilar functions:
|
|
1657
|
-
* - `isValidUrl` which tests any URL
|
|
1658
|
-
* - `isValidPipelineUrl` *(this one)* which tests just promptbook URL
|
|
1659
|
-
*
|
|
1660
|
-
* @public exported from `@promptbook/utils`
|
|
1661
|
-
*/
|
|
1662
|
-
function isValidUrl(url) {
|
|
1663
|
-
if (typeof url !== 'string') {
|
|
1664
|
-
return false;
|
|
1665
|
-
}
|
|
1666
|
-
try {
|
|
1667
|
-
if (url.startsWith('blob:')) {
|
|
1668
|
-
url = url.replace(/^blob:/, '');
|
|
1669
|
-
}
|
|
1670
|
-
var urlObject = new URL(url /* because fail is handled */);
|
|
1671
|
-
if (!['http:', 'https:', 'data:'].includes(urlObject.protocol)) {
|
|
1672
|
-
return false;
|
|
1673
|
-
}
|
|
1674
|
-
return true;
|
|
1675
|
-
}
|
|
1676
|
-
catch (error) {
|
|
1677
|
-
return false;
|
|
1678
|
-
}
|
|
1679
|
-
}
|
|
1680
|
-
|
|
1681
|
-
/**
|
|
1682
|
-
* Tests if given string is valid pipeline URL URL.
|
|
1683
|
-
*
|
|
1684
|
-
* Note: There are two simmilar functions:
|
|
1685
|
-
* - `isValidUrl` which tests any URL
|
|
1686
|
-
* - `isValidPipelineUrl` *(this one)* which tests just pipeline URL
|
|
1687
|
-
*
|
|
1688
|
-
* @public exported from `@promptbook/utils`
|
|
1689
|
-
*/
|
|
1690
|
-
function isValidPipelineUrl(url) {
|
|
1691
|
-
if (!isValidUrl(url)) {
|
|
1692
|
-
return false;
|
|
1693
|
-
}
|
|
1694
|
-
if (!url.startsWith('https://')) {
|
|
1695
|
-
return false;
|
|
1696
|
-
}
|
|
1697
|
-
if (!(url.endsWith('.book.md') || url.endsWith('.book') || url.endsWith('.book.md') || url.endsWith('.ptbk'))) {
|
|
1698
|
-
return false;
|
|
1699
|
-
}
|
|
1700
|
-
if (url.includes('#')) {
|
|
1701
|
-
// TODO: [🐠]
|
|
1702
|
-
return false;
|
|
1703
|
-
}
|
|
1704
|
-
if (isUrlOnPrivateNetwork(url)) {
|
|
1705
|
-
return false;
|
|
1706
|
-
}
|
|
1707
|
-
return true;
|
|
1708
|
-
}
|
|
1709
|
-
/**
|
|
1710
|
-
* TODO: [🐠] Maybe more info why the URL is invalid
|
|
1711
|
-
*/
|
|
1712
|
-
|
|
1713
|
-
/**
|
|
1714
|
-
* Validates PipelineJson if it is logically valid
|
|
1715
|
-
*
|
|
1716
|
-
* It checks:
|
|
1717
|
-
* - if it has correct parameters dependency
|
|
1718
|
-
*
|
|
1719
|
-
* It does NOT check:
|
|
1720
|
-
* - if it is valid json
|
|
1721
|
-
* - if it is meaningful
|
|
1722
|
-
*
|
|
1723
|
-
* @param pipeline valid or invalid PipelineJson
|
|
1724
|
-
* @returns the same pipeline if it is logically valid
|
|
1725
|
-
* @throws {PipelineLogicError} on logical error in the pipeline
|
|
1726
|
-
* @public exported from `@promptbook/core`
|
|
1727
|
-
*/
|
|
1728
|
-
function validatePipeline(pipeline) {
|
|
1729
|
-
if (IS_PIPELINE_LOGIC_VALIDATED) {
|
|
1730
|
-
validatePipelineCore(pipeline);
|
|
1150
|
+
function validatePipeline(pipeline) {
|
|
1151
|
+
if (IS_PIPELINE_LOGIC_VALIDATED) {
|
|
1152
|
+
validatePipeline_InnerFunction(pipeline);
|
|
1731
1153
|
}
|
|
1732
1154
|
else {
|
|
1733
1155
|
try {
|
|
1734
|
-
|
|
1156
|
+
validatePipeline_InnerFunction(pipeline);
|
|
1735
1157
|
}
|
|
1736
1158
|
catch (error) {
|
|
1737
1159
|
if (!(error instanceof PipelineLogicError)) {
|
|
@@ -1745,7 +1167,7 @@
|
|
|
1745
1167
|
/**
|
|
1746
1168
|
* @private internal function for `validatePipeline`
|
|
1747
1169
|
*/
|
|
1748
|
-
function
|
|
1170
|
+
function validatePipeline_InnerFunction(pipeline) {
|
|
1749
1171
|
// TODO: [🧠] Maybe test if promptbook is a promise and make specific error case for that
|
|
1750
1172
|
var e_1, _a, e_2, _b, e_3, _c;
|
|
1751
1173
|
var pipelineIdentification = (function () {
|
|
@@ -1969,11 +1391,11 @@
|
|
|
1969
1391
|
_loop_3();
|
|
1970
1392
|
}
|
|
1971
1393
|
// Note: Check that formfactor is corresponding to the pipeline interface
|
|
1972
|
-
// TODO:
|
|
1394
|
+
// TODO: !!6 Implement this
|
|
1973
1395
|
// pipeline.formfactorName
|
|
1974
1396
|
}
|
|
1975
1397
|
/**
|
|
1976
|
-
* TODO:
|
|
1398
|
+
* TODO: [🧞♀️] Do not allow joker + foreach
|
|
1977
1399
|
* TODO: [🧠] Work with promptbookVersion
|
|
1978
1400
|
* TODO: Use here some json-schema, Zod or something similar and change it to:
|
|
1979
1401
|
* > /**
|
|
@@ -1985,11 +1407,11 @@
|
|
|
1985
1407
|
* > ex port function validatePipeline(promptbook: really_unknown): asserts promptbook is PipelineJson {
|
|
1986
1408
|
*/
|
|
1987
1409
|
/**
|
|
1988
|
-
* TODO: [🧳][main]
|
|
1989
|
-
* TODO: [🧳][🐝][main]
|
|
1990
|
-
* TODO: [🧳][main]
|
|
1991
|
-
* TODO: [🧳][main]
|
|
1992
|
-
* TODO: [🧳][main]
|
|
1410
|
+
* TODO: [🧳][main] !!4 Validate that all examples match expectations
|
|
1411
|
+
* TODO: [🧳][🐝][main] !!4 Validate that knowledge is valid (non-void)
|
|
1412
|
+
* TODO: [🧳][main] !!4 Validate that persona can be used only with CHAT variant
|
|
1413
|
+
* TODO: [🧳][main] !!4 Validate that parameter with reserved name not used RESERVED_PARAMETER_NAMES
|
|
1414
|
+
* TODO: [🧳][main] !!4 Validate that reserved parameter is not used as joker
|
|
1993
1415
|
* TODO: [🧠] Validation not only logic itself but imports around - files and websites and rerefenced pipelines exists
|
|
1994
1416
|
* TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
|
|
1995
1417
|
*/
|
|
@@ -2125,7 +1547,7 @@
|
|
|
2125
1547
|
pipelineJsonToString(unpreparePipeline(pipeline)) !==
|
|
2126
1548
|
pipelineJsonToString(unpreparePipeline(this.collection.get(pipeline.pipelineUrl)))) {
|
|
2127
1549
|
var existing = this.collection.get(pipeline.pipelineUrl);
|
|
2128
|
-
throw new PipelineUrlError(spaceTrim.spaceTrim("\n Pipeline with URL
|
|
1550
|
+
throw new PipelineUrlError(spaceTrim.spaceTrim("\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 ")));
|
|
2129
1551
|
}
|
|
2130
1552
|
// Note: [🧠] Overwrite existing pipeline with the same URL
|
|
2131
1553
|
this.collection.set(pipeline.pipelineUrl, pipeline);
|
|
@@ -2190,6 +1612,38 @@
|
|
|
2190
1612
|
return new (SimplePipelineCollection.bind.apply(SimplePipelineCollection, __spreadArray([void 0], __read(promptbooks), false)))();
|
|
2191
1613
|
}
|
|
2192
1614
|
|
|
1615
|
+
/**
|
|
1616
|
+
* This error type indicates that some tools are missing for pipeline execution or preparation
|
|
1617
|
+
*
|
|
1618
|
+
* @public exported from `@promptbook/core`
|
|
1619
|
+
*/
|
|
1620
|
+
var MissingToolsError = /** @class */ (function (_super) {
|
|
1621
|
+
__extends(MissingToolsError, _super);
|
|
1622
|
+
function MissingToolsError(message) {
|
|
1623
|
+
var _this = _super.call(this, spaceTrim.spaceTrim(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;
|
|
1624
|
+
_this.name = 'MissingToolsError';
|
|
1625
|
+
Object.setPrototypeOf(_this, MissingToolsError.prototype);
|
|
1626
|
+
return _this;
|
|
1627
|
+
}
|
|
1628
|
+
return MissingToolsError;
|
|
1629
|
+
}(Error));
|
|
1630
|
+
|
|
1631
|
+
/**
|
|
1632
|
+
* This error indicates errors during the execution of the pipeline
|
|
1633
|
+
*
|
|
1634
|
+
* @public exported from `@promptbook/core`
|
|
1635
|
+
*/
|
|
1636
|
+
var PipelineExecutionError = /** @class */ (function (_super) {
|
|
1637
|
+
__extends(PipelineExecutionError, _super);
|
|
1638
|
+
function PipelineExecutionError(message) {
|
|
1639
|
+
var _this = _super.call(this, message) || this;
|
|
1640
|
+
_this.name = 'PipelineExecutionError';
|
|
1641
|
+
Object.setPrototypeOf(_this, PipelineExecutionError.prototype);
|
|
1642
|
+
return _this;
|
|
1643
|
+
}
|
|
1644
|
+
return PipelineExecutionError;
|
|
1645
|
+
}(Error));
|
|
1646
|
+
|
|
2193
1647
|
/**
|
|
2194
1648
|
* This error indicates problems parsing the format value
|
|
2195
1649
|
*
|
|
@@ -2429,11 +1883,16 @@
|
|
|
2429
1883
|
/**
|
|
2430
1884
|
* Determine if the pipeline is fully prepared
|
|
2431
1885
|
*
|
|
1886
|
+
* @see https://github.com/webgptorg/promptbook/discussions/196
|
|
1887
|
+
*
|
|
2432
1888
|
* @public exported from `@promptbook/core`
|
|
2433
1889
|
*/
|
|
2434
1890
|
function isPipelinePrepared(pipeline) {
|
|
2435
1891
|
// Note: Ignoring `pipeline.preparations` @@@
|
|
2436
1892
|
// Note: Ignoring `pipeline.knowledgePieces` @@@
|
|
1893
|
+
if (pipeline.title === undefined || pipeline.title === '' || pipeline.title === DEFAULT_BOOK_TITLE) {
|
|
1894
|
+
return false;
|
|
1895
|
+
}
|
|
2437
1896
|
if (!pipeline.personas.every(function (persona) { return persona.modelRequirements !== undefined; })) {
|
|
2438
1897
|
return false;
|
|
2439
1898
|
}
|
|
@@ -2449,7 +1908,7 @@
|
|
|
2449
1908
|
return true;
|
|
2450
1909
|
}
|
|
2451
1910
|
/**
|
|
2452
|
-
* TODO: [🔃][main]
|
|
1911
|
+
* TODO: [🔃][main] If the pipeline was prepared with different version or different set of models, prepare it once again
|
|
2453
1912
|
* TODO: [🐠] Maybe base this on `makeValidator`
|
|
2454
1913
|
* TODO: [🧊] Pipeline can be partially prepared, this should return true ONLY if fully prepared
|
|
2455
1914
|
* TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
|
|
@@ -2458,6 +1917,81 @@
|
|
|
2458
1917
|
* - [♨] Are tasks prepared
|
|
2459
1918
|
*/
|
|
2460
1919
|
|
|
1920
|
+
/**
|
|
1921
|
+
* Format either small or big number
|
|
1922
|
+
*
|
|
1923
|
+
* @public exported from `@promptbook/utils`
|
|
1924
|
+
*/
|
|
1925
|
+
function numberToString(value) {
|
|
1926
|
+
if (value === 0) {
|
|
1927
|
+
return '0';
|
|
1928
|
+
}
|
|
1929
|
+
else if (Number.isNaN(value)) {
|
|
1930
|
+
return VALUE_STRINGS.nan;
|
|
1931
|
+
}
|
|
1932
|
+
else if (value === Infinity) {
|
|
1933
|
+
return VALUE_STRINGS.infinity;
|
|
1934
|
+
}
|
|
1935
|
+
else if (value === -Infinity) {
|
|
1936
|
+
return VALUE_STRINGS.negativeInfinity;
|
|
1937
|
+
}
|
|
1938
|
+
for (var exponent = 0; exponent < 15; exponent++) {
|
|
1939
|
+
var factor = Math.pow(10, exponent);
|
|
1940
|
+
var valueRounded = Math.round(value * factor) / factor;
|
|
1941
|
+
if (Math.abs(value - valueRounded) / value < SMALL_NUMBER) {
|
|
1942
|
+
return valueRounded.toFixed(exponent);
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
return value.toString();
|
|
1946
|
+
}
|
|
1947
|
+
|
|
1948
|
+
/**
|
|
1949
|
+
* Function `valueToString` will convert the given value to string
|
|
1950
|
+
* This is useful and used in the `templateParameters` function
|
|
1951
|
+
*
|
|
1952
|
+
* Note: This function is not just calling `toString` method
|
|
1953
|
+
* It's more complex and can handle this conversion specifically for LLM models
|
|
1954
|
+
* See `VALUE_STRINGS`
|
|
1955
|
+
*
|
|
1956
|
+
* Note: There are 2 similar functions
|
|
1957
|
+
* - `valueToString` converts value to string for LLM models as human-readable string
|
|
1958
|
+
* - `asSerializable` converts value to string to preserve full information to be able to convert it back
|
|
1959
|
+
*
|
|
1960
|
+
* @public exported from `@promptbook/utils`
|
|
1961
|
+
*/
|
|
1962
|
+
function valueToString(value) {
|
|
1963
|
+
try {
|
|
1964
|
+
if (value === '') {
|
|
1965
|
+
return VALUE_STRINGS.empty;
|
|
1966
|
+
}
|
|
1967
|
+
else if (value === null) {
|
|
1968
|
+
return VALUE_STRINGS.null;
|
|
1969
|
+
}
|
|
1970
|
+
else if (value === undefined) {
|
|
1971
|
+
return VALUE_STRINGS.undefined;
|
|
1972
|
+
}
|
|
1973
|
+
else if (typeof value === 'string') {
|
|
1974
|
+
return value;
|
|
1975
|
+
}
|
|
1976
|
+
else if (typeof value === 'number') {
|
|
1977
|
+
return numberToString(value);
|
|
1978
|
+
}
|
|
1979
|
+
else if (value instanceof Date) {
|
|
1980
|
+
return value.toISOString();
|
|
1981
|
+
}
|
|
1982
|
+
else {
|
|
1983
|
+
return JSON.stringify(value);
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
catch (error) {
|
|
1987
|
+
if (!(error instanceof Error)) {
|
|
1988
|
+
throw error;
|
|
1989
|
+
}
|
|
1990
|
+
console.error(error);
|
|
1991
|
+
return VALUE_STRINGS.unserializable;
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
|
|
2461
1995
|
/**
|
|
2462
1996
|
* Serializes an error into a [🚉] JSON-serializable object
|
|
2463
1997
|
*
|
|
@@ -2476,47 +2010,175 @@
|
|
|
2476
2010
|
}
|
|
2477
2011
|
|
|
2478
2012
|
/**
|
|
2479
|
-
*
|
|
2013
|
+
* Represents the usage with no resources consumed
|
|
2480
2014
|
*
|
|
2481
|
-
* @
|
|
2482
|
-
* @returns the list of variable names
|
|
2483
|
-
* @throws {ParseError} if the script is invalid
|
|
2484
|
-
* @public exported from `@promptbook/utils` <- Note: [👖] This is usable elsewhere than in Promptbook, so keeping in utils
|
|
2015
|
+
* @public exported from `@promptbook/core`
|
|
2485
2016
|
*/
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2017
|
+
var ZERO_USAGE = $deepFreeze({
|
|
2018
|
+
price: { value: 0 },
|
|
2019
|
+
input: {
|
|
2020
|
+
tokensCount: { value: 0 },
|
|
2021
|
+
charactersCount: { value: 0 },
|
|
2022
|
+
wordsCount: { value: 0 },
|
|
2023
|
+
sentencesCount: { value: 0 },
|
|
2024
|
+
linesCount: { value: 0 },
|
|
2025
|
+
paragraphsCount: { value: 0 },
|
|
2026
|
+
pagesCount: { value: 0 },
|
|
2027
|
+
},
|
|
2028
|
+
output: {
|
|
2029
|
+
tokensCount: { value: 0 },
|
|
2030
|
+
charactersCount: { value: 0 },
|
|
2031
|
+
wordsCount: { value: 0 },
|
|
2032
|
+
sentencesCount: { value: 0 },
|
|
2033
|
+
linesCount: { value: 0 },
|
|
2034
|
+
paragraphsCount: { value: 0 },
|
|
2035
|
+
pagesCount: { value: 0 },
|
|
2036
|
+
},
|
|
2037
|
+
});
|
|
2038
|
+
/**
|
|
2039
|
+
* Represents the usage with unknown resources consumed
|
|
2040
|
+
*
|
|
2041
|
+
* @public exported from `@promptbook/core`
|
|
2042
|
+
*/
|
|
2043
|
+
$deepFreeze({
|
|
2044
|
+
price: { value: 0, isUncertain: true },
|
|
2045
|
+
input: {
|
|
2046
|
+
tokensCount: { value: 0, isUncertain: true },
|
|
2047
|
+
charactersCount: { value: 0, isUncertain: true },
|
|
2048
|
+
wordsCount: { value: 0, isUncertain: true },
|
|
2049
|
+
sentencesCount: { value: 0, isUncertain: true },
|
|
2050
|
+
linesCount: { value: 0, isUncertain: true },
|
|
2051
|
+
paragraphsCount: { value: 0, isUncertain: true },
|
|
2052
|
+
pagesCount: { value: 0, isUncertain: true },
|
|
2053
|
+
},
|
|
2054
|
+
output: {
|
|
2055
|
+
tokensCount: { value: 0, isUncertain: true },
|
|
2056
|
+
charactersCount: { value: 0, isUncertain: true },
|
|
2057
|
+
wordsCount: { value: 0, isUncertain: true },
|
|
2058
|
+
sentencesCount: { value: 0, isUncertain: true },
|
|
2059
|
+
linesCount: { value: 0, isUncertain: true },
|
|
2060
|
+
paragraphsCount: { value: 0, isUncertain: true },
|
|
2061
|
+
pagesCount: { value: 0, isUncertain: true },
|
|
2062
|
+
},
|
|
2063
|
+
});
|
|
2064
|
+
/**
|
|
2065
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
2066
|
+
*/
|
|
2067
|
+
|
|
2068
|
+
/**
|
|
2069
|
+
* Function `addUsage` will add multiple usages into one
|
|
2070
|
+
*
|
|
2071
|
+
* Note: If you provide 0 values, it returns ZERO_USAGE
|
|
2072
|
+
*
|
|
2073
|
+
* @public exported from `@promptbook/core`
|
|
2074
|
+
*/
|
|
2075
|
+
function addUsage() {
|
|
2076
|
+
var usageItems = [];
|
|
2077
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
2078
|
+
usageItems[_i] = arguments[_i];
|
|
2079
|
+
}
|
|
2080
|
+
return usageItems.reduce(function (acc, item) {
|
|
2081
|
+
var e_1, _a, e_2, _b;
|
|
2082
|
+
var _c;
|
|
2083
|
+
acc.price.value += ((_c = item.price) === null || _c === void 0 ? void 0 : _c.value) || 0;
|
|
2084
|
+
try {
|
|
2085
|
+
for (var _d = __values(Object.keys(acc.input)), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
2086
|
+
var key = _e.value;
|
|
2087
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2088
|
+
//@ts-ignore
|
|
2089
|
+
if (item.input[key]) {
|
|
2090
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2091
|
+
//@ts-ignore
|
|
2092
|
+
acc.input[key].value += item.input[key].value || 0;
|
|
2093
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2094
|
+
//@ts-ignore
|
|
2095
|
+
if (item.input[key].isUncertain) {
|
|
2096
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2097
|
+
//@ts-ignore
|
|
2098
|
+
acc.input[key].isUncertain = true;
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
}
|
|
2103
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
2104
|
+
finally {
|
|
2105
|
+
try {
|
|
2106
|
+
if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
|
|
2107
|
+
}
|
|
2108
|
+
finally { if (e_1) throw e_1.error; }
|
|
2109
|
+
}
|
|
2110
|
+
try {
|
|
2111
|
+
for (var _f = __values(Object.keys(acc.output)), _g = _f.next(); !_g.done; _g = _f.next()) {
|
|
2112
|
+
var key = _g.value;
|
|
2113
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2114
|
+
//@ts-ignore
|
|
2115
|
+
if (item.output[key]) {
|
|
2116
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2117
|
+
//@ts-ignore
|
|
2118
|
+
acc.output[key].value += item.output[key].value || 0;
|
|
2119
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2120
|
+
//@ts-ignore
|
|
2121
|
+
if (item.output[key].isUncertain) {
|
|
2122
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2123
|
+
//@ts-ignore
|
|
2124
|
+
acc.output[key].isUncertain = true;
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
2130
|
+
finally {
|
|
2131
|
+
try {
|
|
2132
|
+
if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
|
|
2133
|
+
}
|
|
2134
|
+
finally { if (e_2) throw e_2.error; }
|
|
2135
|
+
}
|
|
2136
|
+
return acc;
|
|
2137
|
+
}, deepClone(ZERO_USAGE));
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
/**
|
|
2141
|
+
* Parses the given script and returns the list of all used variables that are not defined in the script
|
|
2142
|
+
*
|
|
2143
|
+
* @param script from which to extract the variables
|
|
2144
|
+
* @returns the list of variable names
|
|
2145
|
+
* @throws {ParseError} if the script is invalid
|
|
2146
|
+
* @public exported from `@promptbook/utils` <- Note: [👖] This is usable elsewhere than in Promptbook, so keeping in utils
|
|
2147
|
+
*/
|
|
2148
|
+
function extractVariablesFromScript(script) {
|
|
2149
|
+
var variables = new Set();
|
|
2150
|
+
var originalScript = script;
|
|
2151
|
+
script = "(()=>{".concat(script, "})()");
|
|
2152
|
+
try {
|
|
2153
|
+
for (var i = 0; i < 100 /* <- TODO: This limit to configuration */; i++)
|
|
2154
|
+
try {
|
|
2155
|
+
eval(script);
|
|
2156
|
+
}
|
|
2157
|
+
catch (error) {
|
|
2158
|
+
if (!(error instanceof ReferenceError)) {
|
|
2159
|
+
throw error;
|
|
2160
|
+
}
|
|
2161
|
+
/*
|
|
2162
|
+
Note: Parsing the error
|
|
2163
|
+
🌟 Most devices:
|
|
2164
|
+
[PipelineUrlError: thing is not defined]
|
|
2165
|
+
|
|
2166
|
+
🍏 iPhone`s Safari:
|
|
2167
|
+
[PipelineUrlError: Can't find variable: thing]
|
|
2168
|
+
*/
|
|
2169
|
+
var variableName = undefined;
|
|
2170
|
+
if (error.message.startsWith("Can't")) {
|
|
2171
|
+
// 🍏 Case
|
|
2172
|
+
variableName = error.message.split(' ').pop();
|
|
2173
|
+
}
|
|
2174
|
+
else {
|
|
2175
|
+
// 🌟 Case
|
|
2176
|
+
variableName = error.message.split(' ').shift();
|
|
2177
|
+
}
|
|
2178
|
+
if (variableName === undefined) {
|
|
2179
|
+
throw error;
|
|
2180
|
+
}
|
|
2181
|
+
if (script.includes(variableName + '(')) {
|
|
2520
2182
|
script = "const ".concat(variableName, " = ()=>'';") + script;
|
|
2521
2183
|
}
|
|
2522
2184
|
else {
|
|
@@ -2529,7 +2191,7 @@
|
|
|
2529
2191
|
if (!(error instanceof Error)) {
|
|
2530
2192
|
throw error;
|
|
2531
2193
|
}
|
|
2532
|
-
throw new ParseError(spaceTrim.spaceTrim(function (block) { return "\n Can not extract variables from the script\n
|
|
2194
|
+
throw new ParseError(spaceTrim.spaceTrim(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)
|
|
2533
2195
|
.map(function (variableName, i) { return "".concat(i + 1, ") ").concat(variableName); })
|
|
2534
2196
|
.join('\n'), "\n\n\n The script:\n\n ```javascript\n ").concat(block(originalScript), "\n ```\n "); }));
|
|
2535
2197
|
}
|
|
@@ -2809,27 +2471,6 @@
|
|
|
2809
2471
|
* TODO: [🏢] Allow to expect something inside CSV objects and other formats
|
|
2810
2472
|
*/
|
|
2811
2473
|
|
|
2812
|
-
/**
|
|
2813
|
-
* Function isValidJsonString will tell you if the string is valid JSON or not
|
|
2814
|
-
*
|
|
2815
|
-
* @public exported from `@promptbook/utils`
|
|
2816
|
-
*/
|
|
2817
|
-
function isValidJsonString(value /* <- [👨⚖️] */) {
|
|
2818
|
-
try {
|
|
2819
|
-
JSON.parse(value);
|
|
2820
|
-
return true;
|
|
2821
|
-
}
|
|
2822
|
-
catch (error) {
|
|
2823
|
-
if (!(error instanceof Error)) {
|
|
2824
|
-
throw error;
|
|
2825
|
-
}
|
|
2826
|
-
if (error.message.includes('Unexpected token')) {
|
|
2827
|
-
return false;
|
|
2828
|
-
}
|
|
2829
|
-
return false;
|
|
2830
|
-
}
|
|
2831
|
-
}
|
|
2832
|
-
|
|
2833
2474
|
/**
|
|
2834
2475
|
* Definition for JSON format
|
|
2835
2476
|
*
|
|
@@ -2900,137 +2541,429 @@
|
|
|
2900
2541
|
mappedLines = _a.sent();
|
|
2901
2542
|
return [2 /*return*/, mappedLines.join('\n')];
|
|
2902
2543
|
}
|
|
2903
|
-
});
|
|
2904
|
-
});
|
|
2905
|
-
},
|
|
2906
|
-
},
|
|
2907
|
-
// <- TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
|
|
2908
|
-
],
|
|
2909
|
-
};
|
|
2544
|
+
});
|
|
2545
|
+
});
|
|
2546
|
+
},
|
|
2547
|
+
},
|
|
2548
|
+
// <- TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
|
|
2549
|
+
],
|
|
2550
|
+
};
|
|
2551
|
+
/**
|
|
2552
|
+
* TODO: [1] Make type for XML Text and Schema
|
|
2553
|
+
* TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
|
|
2554
|
+
* TODO: [🍓] In `TextFormatDefinition` implement simple `isValid`
|
|
2555
|
+
* TODO: [🍓] In `TextFormatDefinition` implement partial `canBeValid`
|
|
2556
|
+
* TODO: [🍓] In `TextFormatDefinition` implement `heal
|
|
2557
|
+
* TODO: [🍓] In `TextFormatDefinition` implement `subvalueDefinitions`
|
|
2558
|
+
* TODO: [🏢] Allow to expect something inside each item of list and other formats
|
|
2559
|
+
*/
|
|
2560
|
+
|
|
2561
|
+
/**
|
|
2562
|
+
* Definition for XML format
|
|
2563
|
+
*
|
|
2564
|
+
* @private still in development [🏢]
|
|
2565
|
+
*/
|
|
2566
|
+
var XmlFormatDefinition = {
|
|
2567
|
+
formatName: 'XML',
|
|
2568
|
+
mimeType: 'application/xml',
|
|
2569
|
+
isValid: function (value, settings, schema) {
|
|
2570
|
+
return true;
|
|
2571
|
+
},
|
|
2572
|
+
canBeValid: function (partialValue, settings, schema) {
|
|
2573
|
+
return true;
|
|
2574
|
+
},
|
|
2575
|
+
heal: function (value, settings, schema) {
|
|
2576
|
+
throw new Error('Not implemented');
|
|
2577
|
+
},
|
|
2578
|
+
subvalueDefinitions: [],
|
|
2579
|
+
};
|
|
2580
|
+
/**
|
|
2581
|
+
* TODO: [🧠] Maybe propper instance of object
|
|
2582
|
+
* TODO: [0] Make string_serialized_xml
|
|
2583
|
+
* TODO: [1] Make type for XML Settings and Schema
|
|
2584
|
+
* TODO: [🧠] What to use for validating XMLs - XSD,...
|
|
2585
|
+
* TODO: [🍓] In `XmlFormatDefinition` implement simple `isValid`
|
|
2586
|
+
* TODO: [🍓] In `XmlFormatDefinition` implement partial `canBeValid`
|
|
2587
|
+
* TODO: [🍓] In `XmlFormatDefinition` implement `heal
|
|
2588
|
+
* TODO: [🍓] In `XmlFormatDefinition` implement `subvalueDefinitions`
|
|
2589
|
+
* TODO: [🏢] Allow to expect something inside XML and other formats
|
|
2590
|
+
*/
|
|
2591
|
+
|
|
2592
|
+
/**
|
|
2593
|
+
* Definitions for all formats supported by Promptbook
|
|
2594
|
+
*
|
|
2595
|
+
* @private internal index of `...` <- TODO [🏢]
|
|
2596
|
+
*/
|
|
2597
|
+
var FORMAT_DEFINITIONS = [
|
|
2598
|
+
JsonFormatDefinition,
|
|
2599
|
+
XmlFormatDefinition,
|
|
2600
|
+
TextFormatDefinition,
|
|
2601
|
+
CsvFormatDefinition,
|
|
2602
|
+
];
|
|
2603
|
+
/**
|
|
2604
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
2605
|
+
*/
|
|
2606
|
+
|
|
2607
|
+
/**
|
|
2608
|
+
* Maps available parameters to expected parameters
|
|
2609
|
+
*
|
|
2610
|
+
* The strategy is:
|
|
2611
|
+
* 1) @@@
|
|
2612
|
+
* 2) @@@
|
|
2613
|
+
*
|
|
2614
|
+
* @throws {PipelineExecutionError} @@@
|
|
2615
|
+
* @private within the repository used in `createPipelineExecutor`
|
|
2616
|
+
*/
|
|
2617
|
+
function mapAvailableToExpectedParameters(options) {
|
|
2618
|
+
var e_1, _a;
|
|
2619
|
+
var expectedParameters = options.expectedParameters, availableParameters = options.availableParameters;
|
|
2620
|
+
var availableParametersNames = new Set(Object.keys(availableParameters));
|
|
2621
|
+
var expectedParameterNames = new Set(Object.keys(expectedParameters));
|
|
2622
|
+
var mappedParameters = {};
|
|
2623
|
+
try {
|
|
2624
|
+
// Phase 1️⃣: Matching mapping
|
|
2625
|
+
for (var _b = __values(Array.from(union(availableParametersNames, expectedParameterNames))), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
2626
|
+
var parameterName = _c.value;
|
|
2627
|
+
// Situation: Parameter is available and expected
|
|
2628
|
+
if (availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
|
|
2629
|
+
mappedParameters[parameterName] = availableParameters[parameterName];
|
|
2630
|
+
// <- Note: [👩👩👧] Maybe detect parameter collision here?
|
|
2631
|
+
availableParametersNames.delete(parameterName);
|
|
2632
|
+
expectedParameterNames.delete(parameterName);
|
|
2633
|
+
}
|
|
2634
|
+
// Situation: Parameter is available but NOT expected
|
|
2635
|
+
else if (availableParametersNames.has(parameterName) && !expectedParameterNames.has(parameterName)) {
|
|
2636
|
+
// [🐱👤] Do not pass this parameter to prompt - Maybe use it non-matching mapping
|
|
2637
|
+
}
|
|
2638
|
+
// Situation: Parameter is NOT available BUT expected
|
|
2639
|
+
else if (!availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
|
|
2640
|
+
// Do nothing here - this will be maybe fixed in the non-matching mapping
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
2645
|
+
finally {
|
|
2646
|
+
try {
|
|
2647
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
2648
|
+
}
|
|
2649
|
+
finally { if (e_1) throw e_1.error; }
|
|
2650
|
+
}
|
|
2651
|
+
if (expectedParameterNames.size === 0) {
|
|
2652
|
+
// Note: [👨👨👧] Now we can freeze `mappedParameters` to prevent @@@
|
|
2653
|
+
Object.freeze(mappedParameters);
|
|
2654
|
+
return mappedParameters;
|
|
2655
|
+
}
|
|
2656
|
+
// Phase 2️⃣: Non-matching mapping
|
|
2657
|
+
if (expectedParameterNames.size !== availableParametersNames.size) {
|
|
2658
|
+
throw new PipelineExecutionError(spaceTrim__default["default"](function (block) { return "\n Can not map available parameters to expected parameters\n\n Mapped parameters:\n ".concat(block(Object.keys(mappedParameters)
|
|
2659
|
+
.map(function (parameterName) { return "- {".concat(parameterName, "}"); })
|
|
2660
|
+
.join('\n')), "\n\n Expected parameters which can not be mapped:\n ").concat(block(Array.from(expectedParameterNames)
|
|
2661
|
+
.map(function (parameterName) { return "- {".concat(parameterName, "}"); })
|
|
2662
|
+
.join('\n')), "\n\n Remaining available parameters:\n ").concat(block(Array.from(availableParametersNames)
|
|
2663
|
+
.map(function (parameterName) { return "- {".concat(parameterName, "}"); })
|
|
2664
|
+
.join('\n')), "\n\n "); }));
|
|
2665
|
+
}
|
|
2666
|
+
var expectedParameterNamesArray = Array.from(expectedParameterNames);
|
|
2667
|
+
var availableParametersNamesArray = Array.from(availableParametersNames);
|
|
2668
|
+
for (var i = 0; i < expectedParameterNames.size; i++) {
|
|
2669
|
+
mappedParameters[expectedParameterNamesArray[i]] = availableParameters[availableParametersNamesArray[i]];
|
|
2670
|
+
}
|
|
2671
|
+
// Note: [👨👨👧] Now we can freeze `mappedParameters` to prevent @@@
|
|
2672
|
+
Object.freeze(mappedParameters);
|
|
2673
|
+
return mappedParameters;
|
|
2674
|
+
}
|
|
2675
|
+
|
|
2676
|
+
/**
|
|
2677
|
+
* Multiple LLM Execution Tools is a proxy server that uses multiple execution tools internally and exposes the executor interface externally.
|
|
2678
|
+
*
|
|
2679
|
+
* Note: Internal utility of `joinLlmExecutionTools` but exposed type
|
|
2680
|
+
* @public exported from `@promptbook/core`
|
|
2681
|
+
*/
|
|
2682
|
+
var MultipleLlmExecutionTools = /** @class */ (function () {
|
|
2683
|
+
/**
|
|
2684
|
+
* Gets array of execution tools in order of priority
|
|
2685
|
+
*/
|
|
2686
|
+
function MultipleLlmExecutionTools() {
|
|
2687
|
+
var llmExecutionTools = [];
|
|
2688
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
2689
|
+
llmExecutionTools[_i] = arguments[_i];
|
|
2690
|
+
}
|
|
2691
|
+
this.llmExecutionTools = llmExecutionTools;
|
|
2692
|
+
}
|
|
2693
|
+
Object.defineProperty(MultipleLlmExecutionTools.prototype, "title", {
|
|
2694
|
+
get: function () {
|
|
2695
|
+
return 'Multiple LLM Providers';
|
|
2696
|
+
},
|
|
2697
|
+
enumerable: false,
|
|
2698
|
+
configurable: true
|
|
2699
|
+
});
|
|
2700
|
+
Object.defineProperty(MultipleLlmExecutionTools.prototype, "description", {
|
|
2701
|
+
get: function () {
|
|
2702
|
+
return this.llmExecutionTools.map(function (_a, index) {
|
|
2703
|
+
var title = _a.title;
|
|
2704
|
+
return "".concat(index + 1, ") `").concat(title, "`");
|
|
2705
|
+
}).join('\n');
|
|
2706
|
+
},
|
|
2707
|
+
enumerable: false,
|
|
2708
|
+
configurable: true
|
|
2709
|
+
});
|
|
2710
|
+
/**
|
|
2711
|
+
* Check the configuration of all execution tools
|
|
2712
|
+
*/
|
|
2713
|
+
MultipleLlmExecutionTools.prototype.checkConfiguration = function () {
|
|
2714
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2715
|
+
var _a, _b, llmExecutionTools, e_1_1;
|
|
2716
|
+
var e_1, _c;
|
|
2717
|
+
return __generator(this, function (_d) {
|
|
2718
|
+
switch (_d.label) {
|
|
2719
|
+
case 0:
|
|
2720
|
+
_d.trys.push([0, 5, 6, 7]);
|
|
2721
|
+
_a = __values(this.llmExecutionTools), _b = _a.next();
|
|
2722
|
+
_d.label = 1;
|
|
2723
|
+
case 1:
|
|
2724
|
+
if (!!_b.done) return [3 /*break*/, 4];
|
|
2725
|
+
llmExecutionTools = _b.value;
|
|
2726
|
+
return [4 /*yield*/, llmExecutionTools.checkConfiguration()];
|
|
2727
|
+
case 2:
|
|
2728
|
+
_d.sent();
|
|
2729
|
+
_d.label = 3;
|
|
2730
|
+
case 3:
|
|
2731
|
+
_b = _a.next();
|
|
2732
|
+
return [3 /*break*/, 1];
|
|
2733
|
+
case 4: return [3 /*break*/, 7];
|
|
2734
|
+
case 5:
|
|
2735
|
+
e_1_1 = _d.sent();
|
|
2736
|
+
e_1 = { error: e_1_1 };
|
|
2737
|
+
return [3 /*break*/, 7];
|
|
2738
|
+
case 6:
|
|
2739
|
+
try {
|
|
2740
|
+
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
2741
|
+
}
|
|
2742
|
+
finally { if (e_1) throw e_1.error; }
|
|
2743
|
+
return [7 /*endfinally*/];
|
|
2744
|
+
case 7: return [2 /*return*/];
|
|
2745
|
+
}
|
|
2746
|
+
});
|
|
2747
|
+
});
|
|
2748
|
+
};
|
|
2749
|
+
/**
|
|
2750
|
+
* List all available models that can be used
|
|
2751
|
+
* This lists is a combination of all available models from all execution tools
|
|
2752
|
+
*/
|
|
2753
|
+
MultipleLlmExecutionTools.prototype.listModels = function () {
|
|
2754
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2755
|
+
var availableModels, _a, _b, llmExecutionTools, models, e_2_1;
|
|
2756
|
+
var e_2, _c;
|
|
2757
|
+
return __generator(this, function (_d) {
|
|
2758
|
+
switch (_d.label) {
|
|
2759
|
+
case 0:
|
|
2760
|
+
availableModels = [];
|
|
2761
|
+
_d.label = 1;
|
|
2762
|
+
case 1:
|
|
2763
|
+
_d.trys.push([1, 6, 7, 8]);
|
|
2764
|
+
_a = __values(this.llmExecutionTools), _b = _a.next();
|
|
2765
|
+
_d.label = 2;
|
|
2766
|
+
case 2:
|
|
2767
|
+
if (!!_b.done) return [3 /*break*/, 5];
|
|
2768
|
+
llmExecutionTools = _b.value;
|
|
2769
|
+
return [4 /*yield*/, llmExecutionTools.listModels()];
|
|
2770
|
+
case 3:
|
|
2771
|
+
models = _d.sent();
|
|
2772
|
+
availableModels.push.apply(availableModels, __spreadArray([], __read(models), false));
|
|
2773
|
+
_d.label = 4;
|
|
2774
|
+
case 4:
|
|
2775
|
+
_b = _a.next();
|
|
2776
|
+
return [3 /*break*/, 2];
|
|
2777
|
+
case 5: return [3 /*break*/, 8];
|
|
2778
|
+
case 6:
|
|
2779
|
+
e_2_1 = _d.sent();
|
|
2780
|
+
e_2 = { error: e_2_1 };
|
|
2781
|
+
return [3 /*break*/, 8];
|
|
2782
|
+
case 7:
|
|
2783
|
+
try {
|
|
2784
|
+
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
2785
|
+
}
|
|
2786
|
+
finally { if (e_2) throw e_2.error; }
|
|
2787
|
+
return [7 /*endfinally*/];
|
|
2788
|
+
case 8: return [2 /*return*/, availableModels];
|
|
2789
|
+
}
|
|
2790
|
+
});
|
|
2791
|
+
});
|
|
2792
|
+
};
|
|
2793
|
+
/**
|
|
2794
|
+
* Calls the best available chat model
|
|
2795
|
+
*/
|
|
2796
|
+
MultipleLlmExecutionTools.prototype.callChatModel = function (prompt) {
|
|
2797
|
+
return this.callCommonModel(prompt);
|
|
2798
|
+
};
|
|
2799
|
+
/**
|
|
2800
|
+
* Calls the best available completion model
|
|
2801
|
+
*/
|
|
2802
|
+
MultipleLlmExecutionTools.prototype.callCompletionModel = function (prompt) {
|
|
2803
|
+
return this.callCommonModel(prompt);
|
|
2804
|
+
};
|
|
2805
|
+
/**
|
|
2806
|
+
* Calls the best available embedding model
|
|
2807
|
+
*/
|
|
2808
|
+
MultipleLlmExecutionTools.prototype.callEmbeddingModel = function (prompt) {
|
|
2809
|
+
return this.callCommonModel(prompt);
|
|
2810
|
+
};
|
|
2811
|
+
// <- Note: [🤖]
|
|
2812
|
+
/**
|
|
2813
|
+
* Calls the best available model
|
|
2814
|
+
*
|
|
2815
|
+
* Note: This should be private or protected but is public to be usable with duck typing
|
|
2816
|
+
*/
|
|
2817
|
+
MultipleLlmExecutionTools.prototype.callCommonModel = function (prompt) {
|
|
2818
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2819
|
+
var errors, _a, _b, llmExecutionTools, _c, error_1, e_3_1;
|
|
2820
|
+
var e_3, _d;
|
|
2821
|
+
var _this = this;
|
|
2822
|
+
return __generator(this, function (_e) {
|
|
2823
|
+
switch (_e.label) {
|
|
2824
|
+
case 0:
|
|
2825
|
+
errors = [];
|
|
2826
|
+
_e.label = 1;
|
|
2827
|
+
case 1:
|
|
2828
|
+
_e.trys.push([1, 15, 16, 17]);
|
|
2829
|
+
_a = __values(this.llmExecutionTools), _b = _a.next();
|
|
2830
|
+
_e.label = 2;
|
|
2831
|
+
case 2:
|
|
2832
|
+
if (!!_b.done) return [3 /*break*/, 14];
|
|
2833
|
+
llmExecutionTools = _b.value;
|
|
2834
|
+
_e.label = 3;
|
|
2835
|
+
case 3:
|
|
2836
|
+
_e.trys.push([3, 12, , 13]);
|
|
2837
|
+
_c = prompt.modelRequirements.modelVariant;
|
|
2838
|
+
switch (_c) {
|
|
2839
|
+
case 'CHAT': return [3 /*break*/, 4];
|
|
2840
|
+
case 'COMPLETION': return [3 /*break*/, 6];
|
|
2841
|
+
case 'EMBEDDING': return [3 /*break*/, 8];
|
|
2842
|
+
}
|
|
2843
|
+
return [3 /*break*/, 10];
|
|
2844
|
+
case 4:
|
|
2845
|
+
if (llmExecutionTools.callChatModel === undefined) {
|
|
2846
|
+
return [3 /*break*/, 13];
|
|
2847
|
+
}
|
|
2848
|
+
return [4 /*yield*/, llmExecutionTools.callChatModel(prompt)];
|
|
2849
|
+
case 5: return [2 /*return*/, _e.sent()];
|
|
2850
|
+
case 6:
|
|
2851
|
+
if (llmExecutionTools.callCompletionModel === undefined) {
|
|
2852
|
+
return [3 /*break*/, 13];
|
|
2853
|
+
}
|
|
2854
|
+
return [4 /*yield*/, llmExecutionTools.callCompletionModel(prompt)];
|
|
2855
|
+
case 7: return [2 /*return*/, _e.sent()];
|
|
2856
|
+
case 8:
|
|
2857
|
+
if (llmExecutionTools.callEmbeddingModel === undefined) {
|
|
2858
|
+
return [3 /*break*/, 13];
|
|
2859
|
+
}
|
|
2860
|
+
return [4 /*yield*/, llmExecutionTools.callEmbeddingModel(prompt)];
|
|
2861
|
+
case 9: return [2 /*return*/, _e.sent()];
|
|
2862
|
+
case 10: throw new UnexpectedError("Unknown model variant \"".concat(prompt.modelRequirements.modelVariant, "\""));
|
|
2863
|
+
case 11: return [3 /*break*/, 13];
|
|
2864
|
+
case 12:
|
|
2865
|
+
error_1 = _e.sent();
|
|
2866
|
+
if (!(error_1 instanceof Error) || error_1 instanceof UnexpectedError) {
|
|
2867
|
+
throw error_1;
|
|
2868
|
+
}
|
|
2869
|
+
errors.push(error_1);
|
|
2870
|
+
return [3 /*break*/, 13];
|
|
2871
|
+
case 13:
|
|
2872
|
+
_b = _a.next();
|
|
2873
|
+
return [3 /*break*/, 2];
|
|
2874
|
+
case 14: return [3 /*break*/, 17];
|
|
2875
|
+
case 15:
|
|
2876
|
+
e_3_1 = _e.sent();
|
|
2877
|
+
e_3 = { error: e_3_1 };
|
|
2878
|
+
return [3 /*break*/, 17];
|
|
2879
|
+
case 16:
|
|
2880
|
+
try {
|
|
2881
|
+
if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
|
|
2882
|
+
}
|
|
2883
|
+
finally { if (e_3) throw e_3.error; }
|
|
2884
|
+
return [7 /*endfinally*/];
|
|
2885
|
+
case 17:
|
|
2886
|
+
if (errors.length === 1) {
|
|
2887
|
+
throw errors[0];
|
|
2888
|
+
}
|
|
2889
|
+
else if (errors.length > 1) {
|
|
2890
|
+
throw new PipelineExecutionError(
|
|
2891
|
+
// TODO: Tell which execution tools failed like
|
|
2892
|
+
// 1) OpenAI throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
2893
|
+
// 2) AnthropicClaude throw PipelineExecutionError: Parameter `{knowledge}` is not defined
|
|
2894
|
+
// 3) ...
|
|
2895
|
+
spaceTrim__default["default"](function (block) { return "\n All execution tools failed:\n\n ".concat(block(errors
|
|
2896
|
+
.map(function (error, i) { return "".concat(i + 1, ") **").concat(error.name || 'Error', ":** ").concat(error.message); })
|
|
2897
|
+
.join('\n')), "\n\n "); }));
|
|
2898
|
+
}
|
|
2899
|
+
else if (this.llmExecutionTools.length === 0) {
|
|
2900
|
+
throw new PipelineExecutionError("You have not provided any `LlmExecutionTools`");
|
|
2901
|
+
}
|
|
2902
|
+
else {
|
|
2903
|
+
throw new PipelineExecutionError(spaceTrim__default["default"](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 "); }));
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2906
|
+
});
|
|
2907
|
+
});
|
|
2908
|
+
};
|
|
2909
|
+
return MultipleLlmExecutionTools;
|
|
2910
|
+
}());
|
|
2910
2911
|
/**
|
|
2911
|
-
* TODO: [
|
|
2912
|
-
* TODO: [
|
|
2913
|
-
*
|
|
2914
|
-
* TODO: [🍓] In `TextFormatDefinition` implement partial `canBeValid`
|
|
2915
|
-
* TODO: [🍓] In `TextFormatDefinition` implement `heal
|
|
2916
|
-
* TODO: [🍓] In `TextFormatDefinition` implement `subvalueDefinitions`
|
|
2917
|
-
* TODO: [🏢] Allow to expect something inside each item of list and other formats
|
|
2912
|
+
* TODO: [🧠][🎛] Aggregating multiple models - have result not only from one first aviable model BUT all of them
|
|
2913
|
+
* 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
|
|
2914
|
+
* Look how `countTotalUsage` (and `cacheLlmTools`) implements it
|
|
2918
2915
|
*/
|
|
2919
2916
|
|
|
2920
2917
|
/**
|
|
2921
|
-
*
|
|
2918
|
+
* Joins multiple LLM Execution Tools into one
|
|
2922
2919
|
*
|
|
2923
|
-
* @
|
|
2924
|
-
*/
|
|
2925
|
-
var XmlFormatDefinition = {
|
|
2926
|
-
formatName: 'XML',
|
|
2927
|
-
mimeType: 'application/xml',
|
|
2928
|
-
isValid: function (value, settings, schema) {
|
|
2929
|
-
return true;
|
|
2930
|
-
},
|
|
2931
|
-
canBeValid: function (partialValue, settings, schema) {
|
|
2932
|
-
return true;
|
|
2933
|
-
},
|
|
2934
|
-
heal: function (value, settings, schema) {
|
|
2935
|
-
throw new Error('Not implemented');
|
|
2936
|
-
},
|
|
2937
|
-
subvalueDefinitions: [],
|
|
2938
|
-
};
|
|
2939
|
-
/**
|
|
2940
|
-
* TODO: [🧠] Maybe propper instance of object
|
|
2941
|
-
* TODO: [0] Make string_serialized_xml
|
|
2942
|
-
* TODO: [1] Make type for XML Settings and Schema
|
|
2943
|
-
* TODO: [🧠] What to use for validating XMLs - XSD,...
|
|
2944
|
-
* TODO: [🍓] In `XmlFormatDefinition` implement simple `isValid`
|
|
2945
|
-
* TODO: [🍓] In `XmlFormatDefinition` implement partial `canBeValid`
|
|
2946
|
-
* TODO: [🍓] In `XmlFormatDefinition` implement `heal
|
|
2947
|
-
* TODO: [🍓] In `XmlFormatDefinition` implement `subvalueDefinitions`
|
|
2948
|
-
* TODO: [🏢] Allow to expect something inside XML and other formats
|
|
2949
|
-
*/
|
|
2950
|
-
|
|
2951
|
-
/**
|
|
2952
|
-
* Definitions for all formats supported by Promptbook
|
|
2920
|
+
* @returns {LlmExecutionTools} Single wrapper for multiple LlmExecutionTools
|
|
2953
2921
|
*
|
|
2954
|
-
*
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
XmlFormatDefinition,
|
|
2959
|
-
TextFormatDefinition,
|
|
2960
|
-
CsvFormatDefinition,
|
|
2961
|
-
];
|
|
2962
|
-
/**
|
|
2963
|
-
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
2964
|
-
*/
|
|
2965
|
-
|
|
2966
|
-
/**
|
|
2967
|
-
* Maps available parameters to expected parameters
|
|
2922
|
+
* 0) If there is no LlmExecutionTools, it warns and returns valid but empty LlmExecutionTools
|
|
2923
|
+
* 1) If there is only one LlmExecutionTools, it returns it wrapped in a proxy object
|
|
2924
|
+
* 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.
|
|
2925
|
+
* 3) When all LlmExecutionTools fail, it throws an error with a list of all errors merged into one
|
|
2968
2926
|
*
|
|
2969
|
-
* The strategy is:
|
|
2970
|
-
* 1) @@@
|
|
2971
|
-
* 2) @@@
|
|
2972
2927
|
*
|
|
2973
|
-
*
|
|
2974
|
-
*
|
|
2928
|
+
* Tip: You don't have to use this function directly, just pass an array of LlmExecutionTools to the `ExecutionTools`
|
|
2929
|
+
*
|
|
2930
|
+
* @public exported from `@promptbook/core`
|
|
2975
2931
|
*/
|
|
2976
|
-
function
|
|
2977
|
-
var
|
|
2978
|
-
var
|
|
2979
|
-
|
|
2980
|
-
var expectedParameterNames = new Set(Object.keys(expectedParameters));
|
|
2981
|
-
var mappedParameters = {};
|
|
2982
|
-
try {
|
|
2983
|
-
// Phase 1️⃣: Matching mapping
|
|
2984
|
-
for (var _b = __values(Array.from(union(availableParametersNames, expectedParameterNames))), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
2985
|
-
var parameterName = _c.value;
|
|
2986
|
-
// Situation: Parameter is available and expected
|
|
2987
|
-
if (availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
|
|
2988
|
-
mappedParameters[parameterName] = availableParameters[parameterName];
|
|
2989
|
-
// <- Note: [👩👩👧] Maybe detect parameter collision here?
|
|
2990
|
-
availableParametersNames.delete(parameterName);
|
|
2991
|
-
expectedParameterNames.delete(parameterName);
|
|
2992
|
-
}
|
|
2993
|
-
// Situation: Parameter is available but NOT expected
|
|
2994
|
-
else if (availableParametersNames.has(parameterName) && !expectedParameterNames.has(parameterName)) {
|
|
2995
|
-
// [🐱👤] Do not pass this parameter to prompt - Maybe use it non-matching mapping
|
|
2996
|
-
}
|
|
2997
|
-
// Situation: Parameter is NOT available BUT expected
|
|
2998
|
-
else if (!availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
|
|
2999
|
-
// Do nothing here - this will be maybe fixed in the non-matching mapping
|
|
3000
|
-
}
|
|
3001
|
-
}
|
|
3002
|
-
}
|
|
3003
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
3004
|
-
finally {
|
|
3005
|
-
try {
|
|
3006
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
3007
|
-
}
|
|
3008
|
-
finally { if (e_1) throw e_1.error; }
|
|
3009
|
-
}
|
|
3010
|
-
if (expectedParameterNames.size === 0) {
|
|
3011
|
-
// Note: [👨👨👧] Now we can freeze `mappedParameters` to prevent @@@
|
|
3012
|
-
Object.freeze(mappedParameters);
|
|
3013
|
-
return mappedParameters;
|
|
3014
|
-
}
|
|
3015
|
-
// Phase 2️⃣: Non-matching mapping
|
|
3016
|
-
if (expectedParameterNames.size !== availableParametersNames.size) {
|
|
3017
|
-
throw new PipelineExecutionError(spaceTrim__default["default"](function (block) { return "\n Can not map available parameters to expected parameters\n\n Mapped parameters:\n ".concat(block(Object.keys(mappedParameters)
|
|
3018
|
-
.map(function (parameterName) { return "- {".concat(parameterName, "}"); })
|
|
3019
|
-
.join('\n')), "\n\n Expected parameters which can not be mapped:\n ").concat(block(Array.from(expectedParameterNames)
|
|
3020
|
-
.map(function (parameterName) { return "- {".concat(parameterName, "}"); })
|
|
3021
|
-
.join('\n')), "\n\n Remaining available parameters:\n ").concat(block(Array.from(availableParametersNames)
|
|
3022
|
-
.map(function (parameterName) { return "- {".concat(parameterName, "}"); })
|
|
3023
|
-
.join('\n')), "\n\n "); }));
|
|
2932
|
+
function joinLlmExecutionTools() {
|
|
2933
|
+
var llmExecutionTools = [];
|
|
2934
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
2935
|
+
llmExecutionTools[_i] = arguments[_i];
|
|
3024
2936
|
}
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
2937
|
+
if (llmExecutionTools.length === 0) {
|
|
2938
|
+
var warningMessage = spaceTrim__default["default"]("\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 ");
|
|
2939
|
+
// TODO: [🟥] Detect browser / node and make it colorfull
|
|
2940
|
+
console.warn(warningMessage);
|
|
2941
|
+
/*
|
|
2942
|
+
return {
|
|
2943
|
+
async listModels() {
|
|
2944
|
+
// TODO: [🟥] Detect browser / node and make it colorfull
|
|
2945
|
+
console.warn(
|
|
2946
|
+
spaceTrim(
|
|
2947
|
+
(block) => `
|
|
2948
|
+
|
|
2949
|
+
You can't list models because you have no LLM Execution Tools defined:
|
|
2950
|
+
|
|
2951
|
+
tl;dr
|
|
2952
|
+
|
|
2953
|
+
${block(warningMessage)}
|
|
2954
|
+
`,
|
|
2955
|
+
),
|
|
2956
|
+
);
|
|
2957
|
+
return [];
|
|
2958
|
+
},
|
|
2959
|
+
};
|
|
2960
|
+
*/
|
|
3029
2961
|
}
|
|
3030
|
-
|
|
3031
|
-
Object.freeze(mappedParameters);
|
|
3032
|
-
return mappedParameters;
|
|
2962
|
+
return new (MultipleLlmExecutionTools.bind.apply(MultipleLlmExecutionTools, __spreadArray([void 0], __read(llmExecutionTools), false)))();
|
|
3033
2963
|
}
|
|
2964
|
+
/**
|
|
2965
|
+
* TODO: [👷♂️] @@@ Manual about construction of llmTools
|
|
2966
|
+
*/
|
|
3034
2967
|
|
|
3035
2968
|
/**
|
|
3036
2969
|
* Extracts all code blocks from markdown.
|
|
@@ -3148,98 +3081,23 @@
|
|
|
3148
3081
|
* TODO: [🏢] Make this logic part of `JsonFormatDefinition` or `isValidJsonString`
|
|
3149
3082
|
*/
|
|
3150
3083
|
|
|
3151
|
-
/**
|
|
3152
|
-
* Takes an item or an array of items and returns an array of items
|
|
3153
|
-
*
|
|
3154
|
-
* 1) Any item except array and undefined returns array with that one item (also null)
|
|
3155
|
-
* 2) Undefined returns empty array
|
|
3156
|
-
* 3) Array returns itself
|
|
3157
|
-
*
|
|
3158
|
-
* @private internal utility
|
|
3159
|
-
*/
|
|
3160
|
-
function arrayableToArray(input) {
|
|
3161
|
-
if (input === undefined) {
|
|
3162
|
-
return [];
|
|
3163
|
-
}
|
|
3164
|
-
if (input instanceof Array) {
|
|
3165
|
-
return input;
|
|
3166
|
-
}
|
|
3167
|
-
return [input];
|
|
3168
|
-
}
|
|
3169
|
-
|
|
3170
|
-
/**
|
|
3171
|
-
* Format either small or big number
|
|
3172
|
-
*
|
|
3173
|
-
* @public exported from `@promptbook/utils`
|
|
3174
|
-
*/
|
|
3175
|
-
function numberToString(value) {
|
|
3176
|
-
if (value === 0) {
|
|
3177
|
-
return '0';
|
|
3178
|
-
}
|
|
3179
|
-
else if (Number.isNaN(value)) {
|
|
3180
|
-
return VALUE_STRINGS.nan;
|
|
3181
|
-
}
|
|
3182
|
-
else if (value === Infinity) {
|
|
3183
|
-
return VALUE_STRINGS.infinity;
|
|
3184
|
-
}
|
|
3185
|
-
else if (value === -Infinity) {
|
|
3186
|
-
return VALUE_STRINGS.negativeInfinity;
|
|
3187
|
-
}
|
|
3188
|
-
for (var exponent = 0; exponent < 15; exponent++) {
|
|
3189
|
-
var factor = Math.pow(10, exponent);
|
|
3190
|
-
var valueRounded = Math.round(value * factor) / factor;
|
|
3191
|
-
if (Math.abs(value - valueRounded) / value < SMALL_NUMBER) {
|
|
3192
|
-
return valueRounded.toFixed(exponent);
|
|
3193
|
-
}
|
|
3194
|
-
}
|
|
3195
|
-
return value.toString();
|
|
3196
|
-
}
|
|
3197
|
-
|
|
3198
|
-
/**
|
|
3199
|
-
* Function `valueToString` will convert the given value to string
|
|
3200
|
-
* This is useful and used in the `templateParameters` function
|
|
3201
|
-
*
|
|
3202
|
-
* Note: This function is not just calling `toString` method
|
|
3203
|
-
* It's more complex and can handle this conversion specifically for LLM models
|
|
3204
|
-
* See `VALUE_STRINGS`
|
|
3084
|
+
/**
|
|
3085
|
+
* Takes an item or an array of items and returns an array of items
|
|
3205
3086
|
*
|
|
3206
|
-
*
|
|
3207
|
-
*
|
|
3208
|
-
*
|
|
3087
|
+
* 1) Any item except array and undefined returns array with that one item (also null)
|
|
3088
|
+
* 2) Undefined returns empty array
|
|
3089
|
+
* 3) Array returns itself
|
|
3209
3090
|
*
|
|
3210
|
-
* @
|
|
3091
|
+
* @private internal utility
|
|
3211
3092
|
*/
|
|
3212
|
-
function
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
return VALUE_STRINGS.empty;
|
|
3216
|
-
}
|
|
3217
|
-
else if (value === null) {
|
|
3218
|
-
return VALUE_STRINGS.null;
|
|
3219
|
-
}
|
|
3220
|
-
else if (value === undefined) {
|
|
3221
|
-
return VALUE_STRINGS.undefined;
|
|
3222
|
-
}
|
|
3223
|
-
else if (typeof value === 'string') {
|
|
3224
|
-
return value;
|
|
3225
|
-
}
|
|
3226
|
-
else if (typeof value === 'number') {
|
|
3227
|
-
return numberToString(value);
|
|
3228
|
-
}
|
|
3229
|
-
else if (value instanceof Date) {
|
|
3230
|
-
return value.toISOString();
|
|
3231
|
-
}
|
|
3232
|
-
else {
|
|
3233
|
-
return JSON.stringify(value);
|
|
3234
|
-
}
|
|
3093
|
+
function arrayableToArray(input) {
|
|
3094
|
+
if (input === undefined) {
|
|
3095
|
+
return [];
|
|
3235
3096
|
}
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
throw error;
|
|
3239
|
-
}
|
|
3240
|
-
console.error(error);
|
|
3241
|
-
return VALUE_STRINGS.unserializable;
|
|
3097
|
+
if (input instanceof Array) {
|
|
3098
|
+
return input;
|
|
3242
3099
|
}
|
|
3100
|
+
return [input];
|
|
3243
3101
|
}
|
|
3244
3102
|
|
|
3245
3103
|
/**
|
|
@@ -3298,6 +3156,8 @@
|
|
|
3298
3156
|
throw new PipelineExecutionError("Parameter `{".concat(parameterName, "}` is not defined"));
|
|
3299
3157
|
}
|
|
3300
3158
|
parameterValue = valueToString(parameterValue);
|
|
3159
|
+
// Escape curly braces in parameter values to prevent prompt-injection
|
|
3160
|
+
parameterValue = parameterValue.replace(/[{}]/g, '\\$&');
|
|
3301
3161
|
if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
|
|
3302
3162
|
parameterValue = parameterValue
|
|
3303
3163
|
.split('\n')
|
|
@@ -3918,7 +3778,7 @@
|
|
|
3918
3778
|
promptTitle: task.title,
|
|
3919
3779
|
promptMessage: templateParameters(task.description || '', parameters),
|
|
3920
3780
|
defaultValue: templateParameters(preparedContent, parameters),
|
|
3921
|
-
// TODO: [🧠]
|
|
3781
|
+
// TODO: [🧠] Figure out how to define placeholder in .book.md file
|
|
3922
3782
|
placeholder: undefined,
|
|
3923
3783
|
priority: priority,
|
|
3924
3784
|
}))];
|
|
@@ -4618,7 +4478,10 @@
|
|
|
4618
4478
|
finally { if (e_2) throw e_2.error; }
|
|
4619
4479
|
return [7 /*endfinally*/];
|
|
4620
4480
|
case 19:
|
|
4621
|
-
parametersToPass = inputParameters
|
|
4481
|
+
parametersToPass = Object.fromEntries(Object.entries(inputParameters).map(function (_a) {
|
|
4482
|
+
var _b = __read(_a, 2), key = _b[0], value = _b[1];
|
|
4483
|
+
return [key, valueToString(value)];
|
|
4484
|
+
}));
|
|
4622
4485
|
_g.label = 20;
|
|
4623
4486
|
case 20:
|
|
4624
4487
|
_g.trys.push([20, 25, , 28]);
|
|
@@ -4853,6 +4716,169 @@
|
|
|
4853
4716
|
* TODO: [🐚] Change onProgress to object that represents the running execution, can be subscribed via RxJS to and also awaited
|
|
4854
4717
|
*/
|
|
4855
4718
|
|
|
4719
|
+
/**
|
|
4720
|
+
* Async version of Array.forEach
|
|
4721
|
+
*
|
|
4722
|
+
* @param array - Array to iterate over
|
|
4723
|
+
* @param options - Options for the function
|
|
4724
|
+
* @param callbackfunction - Function to call for each item
|
|
4725
|
+
* @public exported from `@promptbook/utils`
|
|
4726
|
+
* @deprecated [🪂] Use queues instead
|
|
4727
|
+
*/
|
|
4728
|
+
function forEachAsync(array, options, callbackfunction) {
|
|
4729
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
4730
|
+
var _a, maxParallelCount, index, runningTasks, tasks, _loop_1, _b, _c, item, e_1_1;
|
|
4731
|
+
var e_1, _d;
|
|
4732
|
+
return __generator(this, function (_e) {
|
|
4733
|
+
switch (_e.label) {
|
|
4734
|
+
case 0:
|
|
4735
|
+
_a = options.maxParallelCount, maxParallelCount = _a === void 0 ? Infinity : _a;
|
|
4736
|
+
index = 0;
|
|
4737
|
+
runningTasks = [];
|
|
4738
|
+
tasks = [];
|
|
4739
|
+
_loop_1 = function (item) {
|
|
4740
|
+
var currentIndex, task;
|
|
4741
|
+
return __generator(this, function (_f) {
|
|
4742
|
+
switch (_f.label) {
|
|
4743
|
+
case 0:
|
|
4744
|
+
currentIndex = index++;
|
|
4745
|
+
task = callbackfunction(item, currentIndex, array);
|
|
4746
|
+
tasks.push(task);
|
|
4747
|
+
runningTasks.push(task);
|
|
4748
|
+
/* not await */ Promise.resolve(task).then(function () {
|
|
4749
|
+
runningTasks = runningTasks.filter(function (t) { return t !== task; });
|
|
4750
|
+
});
|
|
4751
|
+
if (!(maxParallelCount < runningTasks.length)) return [3 /*break*/, 2];
|
|
4752
|
+
return [4 /*yield*/, Promise.race(runningTasks)];
|
|
4753
|
+
case 1:
|
|
4754
|
+
_f.sent();
|
|
4755
|
+
_f.label = 2;
|
|
4756
|
+
case 2: return [2 /*return*/];
|
|
4757
|
+
}
|
|
4758
|
+
});
|
|
4759
|
+
};
|
|
4760
|
+
_e.label = 1;
|
|
4761
|
+
case 1:
|
|
4762
|
+
_e.trys.push([1, 6, 7, 8]);
|
|
4763
|
+
_b = __values(array), _c = _b.next();
|
|
4764
|
+
_e.label = 2;
|
|
4765
|
+
case 2:
|
|
4766
|
+
if (!!_c.done) return [3 /*break*/, 5];
|
|
4767
|
+
item = _c.value;
|
|
4768
|
+
return [5 /*yield**/, _loop_1(item)];
|
|
4769
|
+
case 3:
|
|
4770
|
+
_e.sent();
|
|
4771
|
+
_e.label = 4;
|
|
4772
|
+
case 4:
|
|
4773
|
+
_c = _b.next();
|
|
4774
|
+
return [3 /*break*/, 2];
|
|
4775
|
+
case 5: return [3 /*break*/, 8];
|
|
4776
|
+
case 6:
|
|
4777
|
+
e_1_1 = _e.sent();
|
|
4778
|
+
e_1 = { error: e_1_1 };
|
|
4779
|
+
return [3 /*break*/, 8];
|
|
4780
|
+
case 7:
|
|
4781
|
+
try {
|
|
4782
|
+
if (_c && !_c.done && (_d = _b.return)) _d.call(_b);
|
|
4783
|
+
}
|
|
4784
|
+
finally { if (e_1) throw e_1.error; }
|
|
4785
|
+
return [7 /*endfinally*/];
|
|
4786
|
+
case 8: return [4 /*yield*/, Promise.all(tasks)];
|
|
4787
|
+
case 9:
|
|
4788
|
+
_e.sent();
|
|
4789
|
+
return [2 /*return*/];
|
|
4790
|
+
}
|
|
4791
|
+
});
|
|
4792
|
+
});
|
|
4793
|
+
}
|
|
4794
|
+
|
|
4795
|
+
/**
|
|
4796
|
+
* Intercepts LLM tools and counts total usage of the tools
|
|
4797
|
+
*
|
|
4798
|
+
* @param llmTools LLM tools to be intercepted with usage counting
|
|
4799
|
+
* @returns LLM tools with same functionality with added total cost counting
|
|
4800
|
+
* @public exported from `@promptbook/core`
|
|
4801
|
+
*/
|
|
4802
|
+
function countTotalUsage(llmTools) {
|
|
4803
|
+
var _this = this;
|
|
4804
|
+
var totalUsage = ZERO_USAGE;
|
|
4805
|
+
var proxyTools = {
|
|
4806
|
+
get title() {
|
|
4807
|
+
// TODO: [🧠] Maybe put here some suffix
|
|
4808
|
+
return llmTools.title;
|
|
4809
|
+
},
|
|
4810
|
+
get description() {
|
|
4811
|
+
// TODO: [🧠] Maybe put here some suffix
|
|
4812
|
+
return llmTools.description;
|
|
4813
|
+
},
|
|
4814
|
+
checkConfiguration: function () {
|
|
4815
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
4816
|
+
return __generator(this, function (_a) {
|
|
4817
|
+
return [2 /*return*/, /* not await */ llmTools.checkConfiguration()];
|
|
4818
|
+
});
|
|
4819
|
+
});
|
|
4820
|
+
},
|
|
4821
|
+
listModels: function () {
|
|
4822
|
+
return /* not await */ llmTools.listModels();
|
|
4823
|
+
},
|
|
4824
|
+
getTotalUsage: function () {
|
|
4825
|
+
// <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
|
|
4826
|
+
return totalUsage;
|
|
4827
|
+
},
|
|
4828
|
+
};
|
|
4829
|
+
if (llmTools.callChatModel !== undefined) {
|
|
4830
|
+
proxyTools.callChatModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
|
|
4831
|
+
var promptResult;
|
|
4832
|
+
return __generator(this, function (_a) {
|
|
4833
|
+
switch (_a.label) {
|
|
4834
|
+
case 0: return [4 /*yield*/, llmTools.callChatModel(prompt)];
|
|
4835
|
+
case 1:
|
|
4836
|
+
promptResult = _a.sent();
|
|
4837
|
+
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
4838
|
+
return [2 /*return*/, promptResult];
|
|
4839
|
+
}
|
|
4840
|
+
});
|
|
4841
|
+
}); };
|
|
4842
|
+
}
|
|
4843
|
+
if (llmTools.callCompletionModel !== undefined) {
|
|
4844
|
+
proxyTools.callCompletionModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
|
|
4845
|
+
var promptResult;
|
|
4846
|
+
return __generator(this, function (_a) {
|
|
4847
|
+
switch (_a.label) {
|
|
4848
|
+
case 0: return [4 /*yield*/, llmTools.callCompletionModel(prompt)];
|
|
4849
|
+
case 1:
|
|
4850
|
+
promptResult = _a.sent();
|
|
4851
|
+
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
4852
|
+
return [2 /*return*/, promptResult];
|
|
4853
|
+
}
|
|
4854
|
+
});
|
|
4855
|
+
}); };
|
|
4856
|
+
}
|
|
4857
|
+
if (llmTools.callEmbeddingModel !== undefined) {
|
|
4858
|
+
proxyTools.callEmbeddingModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
|
|
4859
|
+
var promptResult;
|
|
4860
|
+
return __generator(this, function (_a) {
|
|
4861
|
+
switch (_a.label) {
|
|
4862
|
+
case 0: return [4 /*yield*/, llmTools.callEmbeddingModel(prompt)];
|
|
4863
|
+
case 1:
|
|
4864
|
+
promptResult = _a.sent();
|
|
4865
|
+
totalUsage = addUsage(totalUsage, promptResult.usage);
|
|
4866
|
+
return [2 /*return*/, promptResult];
|
|
4867
|
+
}
|
|
4868
|
+
});
|
|
4869
|
+
}); };
|
|
4870
|
+
}
|
|
4871
|
+
// <- Note: [🤖]
|
|
4872
|
+
return proxyTools;
|
|
4873
|
+
}
|
|
4874
|
+
/**
|
|
4875
|
+
* TODO: [🧠][💸] Maybe make some common abstraction `interceptLlmTools` and use here (or use javascript Proxy?)
|
|
4876
|
+
* TODO: [🧠] Is there some meaningfull way how to test this util
|
|
4877
|
+
* TODO: [🧠][🌯] Maybe a way how to hide ability to `get totalUsage`
|
|
4878
|
+
* > const [llmToolsWithUsage,getUsage] = countTotalUsage(llmTools);
|
|
4879
|
+
* TODO: [👷♂️] @@@ Manual about construction of llmTools
|
|
4880
|
+
*/
|
|
4881
|
+
|
|
4856
4882
|
/**
|
|
4857
4883
|
* Prepares the persona for the pipeline
|
|
4858
4884
|
*
|
|
@@ -4915,10 +4941,10 @@
|
|
|
4915
4941
|
});
|
|
4916
4942
|
}
|
|
4917
4943
|
/**
|
|
4918
|
-
* TODO: [🔃][main]
|
|
4919
|
-
* TODO: [🏢]
|
|
4920
|
-
* TODO: [🏢]
|
|
4921
|
-
* TODO: [🏢]
|
|
4944
|
+
* TODO: [🔃][main] If the persona was prepared with different version or different set of models, prepare it once again
|
|
4945
|
+
* TODO: [🏢] Check validity of `modelName` in pipeline
|
|
4946
|
+
* TODO: [🏢] Check validity of `systemMessage` in pipeline
|
|
4947
|
+
* TODO: [🏢] Check validity of `temperature` in pipeline
|
|
4922
4948
|
*/
|
|
4923
4949
|
|
|
4924
4950
|
/**
|
|
@@ -5352,21 +5378,44 @@
|
|
|
5352
5378
|
if (typeof filename !== 'string') {
|
|
5353
5379
|
return false;
|
|
5354
5380
|
}
|
|
5381
|
+
if (filename.split('\n').length > 1) {
|
|
5382
|
+
return false;
|
|
5383
|
+
}
|
|
5384
|
+
if (filename.split(' ').length >
|
|
5385
|
+
5 /* <- TODO: [🧠][🈷] Make some better non-arbitrary way how to distinct filenames from informational texts */) {
|
|
5386
|
+
return false;
|
|
5387
|
+
}
|
|
5355
5388
|
var filenameSlashes = filename.split('\\').join('/');
|
|
5356
5389
|
// Absolute Unix path: /hello.txt
|
|
5357
5390
|
if (/^(\/)/i.test(filenameSlashes)) {
|
|
5391
|
+
// console.log(filename, 'Absolute Unix path: /hello.txt');
|
|
5358
5392
|
return true;
|
|
5359
5393
|
}
|
|
5360
5394
|
// Absolute Windows path: /hello.txt
|
|
5361
5395
|
if (/^([A-Z]{1,2}:\/?)\//i.test(filenameSlashes)) {
|
|
5396
|
+
// console.log(filename, 'Absolute Windows path: /hello.txt');
|
|
5362
5397
|
return true;
|
|
5363
5398
|
}
|
|
5364
5399
|
// Relative path: ./hello.txt
|
|
5365
5400
|
if (/^(\.\.?\/)+/i.test(filenameSlashes)) {
|
|
5401
|
+
// console.log(filename, 'Relative path: ./hello.txt');
|
|
5402
|
+
return true;
|
|
5403
|
+
}
|
|
5404
|
+
// Allow paths like foo/hello
|
|
5405
|
+
if (/^[^/]+\/[^/]+/i.test(filenameSlashes)) {
|
|
5406
|
+
// console.log(filename, 'Allow paths like foo/hello');
|
|
5407
|
+
return true;
|
|
5408
|
+
}
|
|
5409
|
+
// Allow paths like hello.book
|
|
5410
|
+
if (/^[^/]+\.[^/]+$/i.test(filenameSlashes)) {
|
|
5411
|
+
// console.log(filename, 'Allow paths like hello.book');
|
|
5366
5412
|
return true;
|
|
5367
5413
|
}
|
|
5368
5414
|
return false;
|
|
5369
5415
|
}
|
|
5416
|
+
/**
|
|
5417
|
+
* TODO: [🍏] Implement for MacOs
|
|
5418
|
+
*/
|
|
5370
5419
|
|
|
5371
5420
|
/**
|
|
5372
5421
|
* The built-in `fetch' function with a lightweight error handling wrapper as default fetch function used in Promptbook scrapers
|
|
@@ -5391,6 +5440,9 @@
|
|
|
5391
5440
|
}
|
|
5392
5441
|
});
|
|
5393
5442
|
}); };
|
|
5443
|
+
/**
|
|
5444
|
+
* TODO: [🧠] Maybe rename because it is not used only for scrapers but also in `$getCompiledBook`
|
|
5445
|
+
*/
|
|
5394
5446
|
|
|
5395
5447
|
/**
|
|
5396
5448
|
* @@@
|
|
@@ -5458,7 +5510,7 @@
|
|
|
5458
5510
|
},
|
|
5459
5511
|
}];
|
|
5460
5512
|
case 2:
|
|
5461
|
-
if (!
|
|
5513
|
+
if (!isValidFilePath(sourceContent)) return [3 /*break*/, 4];
|
|
5462
5514
|
if (tools.fs === undefined) {
|
|
5463
5515
|
throw new EnvironmentMismatchError('Can not import file knowledge without filesystem tools');
|
|
5464
5516
|
// <- TODO: [🧠] What is the best error type here`
|
|
@@ -5473,7 +5525,7 @@
|
|
|
5473
5525
|
return [4 /*yield*/, isFileExisting(filename_1, tools.fs)];
|
|
5474
5526
|
case 3:
|
|
5475
5527
|
if (!(_f.sent())) {
|
|
5476
|
-
throw new NotFoundError(spaceTrim__default["default"](function (block) { return "\n Can not make source handler for file which does not exist:\n\n File:\n ".concat(block(filename_1), "\n "); }));
|
|
5528
|
+
throw new NotFoundError(spaceTrim__default["default"](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 "); }));
|
|
5477
5529
|
}
|
|
5478
5530
|
// TODO: [🧠][😿] Test security file - file is scoped to the project (BUT maybe do this in `filesystemTools`)
|
|
5479
5531
|
return [2 /*return*/, {
|
|
@@ -5586,7 +5638,7 @@
|
|
|
5586
5638
|
partialPieces = __spreadArray([], __read(partialPiecesUnchecked), false);
|
|
5587
5639
|
return [2 /*return*/, "break"];
|
|
5588
5640
|
}
|
|
5589
|
-
console.warn(spaceTrim__default["default"](function (block) { return "\n Cannot scrape knowledge from source despite the scraper `".concat(scraper.metadata.className, "` supports the mime type \"").concat(sourceHandler.mimeType, "\".\n
|
|
5641
|
+
console.warn(spaceTrim__default["default"](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
|
|
5590
5642
|
.split('\n')
|
|
5591
5643
|
.map(function (line) { return "> ".concat(line); })
|
|
5592
5644
|
.join('\n')), "\n\n ").concat(block($registeredScrapersMessage(scrapers)), "\n\n\n "); }));
|
|
@@ -5624,7 +5676,7 @@
|
|
|
5624
5676
|
return [7 /*endfinally*/];
|
|
5625
5677
|
case 9:
|
|
5626
5678
|
if (partialPieces === null) {
|
|
5627
|
-
throw new KnowledgeScrapeError(spaceTrim__default["default"](function (block) { return "\n Cannot scrape knowledge\n
|
|
5679
|
+
throw new KnowledgeScrapeError(spaceTrim__default["default"](function (block) { return "\n Cannot scrape knowledge\n\n The source:\n > ".concat(block(knowledgeSource.sourceContent
|
|
5628
5680
|
.split('\n')
|
|
5629
5681
|
.map(function (line) { return "> ".concat(line); })
|
|
5630
5682
|
.join('\n')), "\n\n No scraper found for the mime type \"").concat(sourceHandler.mimeType, "\"\n\n ").concat(block($registeredScrapersMessage(scrapers)), "\n\n\n "); }));
|
|
@@ -5715,7 +5767,7 @@
|
|
|
5715
5767
|
* TODO: [😂] Adding knowledge should be convert to async high-level abstractions, simmilar thing with expectations to sync high-level abstractions
|
|
5716
5768
|
* TODO: [🧠] Add context to each task (if missing)
|
|
5717
5769
|
* TODO: [🧠] What is better name `prepareTask` or `prepareTaskAndParameters`
|
|
5718
|
-
* TODO: [♨][main]
|
|
5770
|
+
* TODO: [♨][main] !!3 Prepare index the examples and maybe tasks
|
|
5719
5771
|
* TODO: Write tests for `preparePipeline`
|
|
5720
5772
|
* TODO: [🏏] Leverage the batch API and build queues @see https://platform.openai.com/docs/guides/batch
|
|
5721
5773
|
* TODO: [🧊] In future one preparation can take data from previous preparation and save tokens and time
|
|
@@ -5725,6 +5777,8 @@
|
|
|
5725
5777
|
/**
|
|
5726
5778
|
* Prepare pipeline from string (markdown) format to JSON format
|
|
5727
5779
|
*
|
|
5780
|
+
* @see https://github.com/webgptorg/promptbook/discussions/196
|
|
5781
|
+
*
|
|
5728
5782
|
* Note: This function does not validate logic of the pipeline
|
|
5729
5783
|
* Note: This function acts as part of compilation process
|
|
5730
5784
|
* Note: When the pipeline is already prepared, it returns the same pipeline
|
|
@@ -5737,16 +5791,17 @@
|
|
|
5737
5791
|
<- TODO: [🧠][🪑] `promptbookVersion` */
|
|
5738
5792
|
knowledgeSources /*
|
|
5739
5793
|
<- TODO: [🧊] `knowledgePieces` */, personas /*
|
|
5740
|
-
<- TODO: [🧊] `preparations` */, _llms, llmTools, llmToolsWithUsage, currentPreparation, preparations, preparedPersonas, knowledgeSourcesPrepared, partialknowledgePiecesPrepared, knowledgePiecesPrepared, tasksPrepared /* TODO: parameters: parametersPrepared*/;
|
|
5794
|
+
<- TODO: [🧊] `preparations` */, sources, _llms, llmTools, llmToolsWithUsage, currentPreparation, preparations, title, collection, prepareTitleExecutor, _c, result, outputParameters, titleRaw, preparedPersonas, knowledgeSourcesPrepared, partialknowledgePiecesPrepared, knowledgePiecesPrepared, tasksPrepared /* TODO: parameters: parametersPrepared*/;
|
|
5795
|
+
var _d;
|
|
5741
5796
|
var _this = this;
|
|
5742
|
-
return __generator(this, function (
|
|
5743
|
-
switch (
|
|
5797
|
+
return __generator(this, function (_e) {
|
|
5798
|
+
switch (_e.label) {
|
|
5744
5799
|
case 0:
|
|
5745
5800
|
if (isPipelinePrepared(pipeline)) {
|
|
5746
5801
|
return [2 /*return*/, pipeline];
|
|
5747
5802
|
}
|
|
5748
5803
|
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;
|
|
5749
|
-
parameters = pipeline.parameters, tasks = pipeline.tasks, knowledgeSources = pipeline.knowledgeSources, personas = pipeline.personas;
|
|
5804
|
+
parameters = pipeline.parameters, tasks = pipeline.tasks, knowledgeSources = pipeline.knowledgeSources, personas = pipeline.personas, sources = pipeline.sources;
|
|
5750
5805
|
if (tools === undefined || tools.llm === undefined) {
|
|
5751
5806
|
throw new MissingToolsError('LLM tools are required for preparing the pipeline');
|
|
5752
5807
|
}
|
|
@@ -5764,6 +5819,33 @@
|
|
|
5764
5819
|
// <- TODO: [🧊]
|
|
5765
5820
|
currentPreparation,
|
|
5766
5821
|
];
|
|
5822
|
+
title = pipeline.title;
|
|
5823
|
+
if (!(title === undefined || title === '' || title === DEFAULT_BOOK_TITLE)) return [3 /*break*/, 3];
|
|
5824
|
+
collection = createCollectionFromJson.apply(void 0, __spreadArray([], __read(PipelineCollection), false));
|
|
5825
|
+
_c = createPipelineExecutor;
|
|
5826
|
+
_d = {};
|
|
5827
|
+
return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-title.book.md')];
|
|
5828
|
+
case 1:
|
|
5829
|
+
prepareTitleExecutor = _c.apply(void 0, [(_d.pipeline = _e.sent(),
|
|
5830
|
+
_d.tools = tools,
|
|
5831
|
+
_d)]);
|
|
5832
|
+
return [4 /*yield*/, prepareTitleExecutor({
|
|
5833
|
+
book: sources.map(function (_a) {
|
|
5834
|
+
var content = _a.content;
|
|
5835
|
+
return content;
|
|
5836
|
+
}).join('\n\n'),
|
|
5837
|
+
})];
|
|
5838
|
+
case 2:
|
|
5839
|
+
result = _e.sent();
|
|
5840
|
+
assertsExecutionSuccessful(result);
|
|
5841
|
+
outputParameters = result.outputParameters;
|
|
5842
|
+
titleRaw = outputParameters.title;
|
|
5843
|
+
if (isVerbose) {
|
|
5844
|
+
console.info("The title is \"".concat(titleRaw, "\""));
|
|
5845
|
+
}
|
|
5846
|
+
title = titleRaw || DEFAULT_BOOK_TITLE;
|
|
5847
|
+
_e.label = 3;
|
|
5848
|
+
case 3:
|
|
5767
5849
|
preparedPersonas = new Array(personas.length);
|
|
5768
5850
|
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 () {
|
|
5769
5851
|
var modelRequirements, preparedPersona;
|
|
@@ -5782,12 +5864,12 @@
|
|
|
5782
5864
|
}
|
|
5783
5865
|
});
|
|
5784
5866
|
}); })];
|
|
5785
|
-
case
|
|
5786
|
-
|
|
5867
|
+
case 4:
|
|
5868
|
+
_e.sent();
|
|
5787
5869
|
knowledgeSourcesPrepared = knowledgeSources.map(function (source) { return (__assign(__assign({}, source), { preparationIds: [/* TODO: [🧊] -> */ currentPreparation.id] })); });
|
|
5788
5870
|
return [4 /*yield*/, prepareKnowledgePieces(knowledgeSources /* <- TODO: [🧊] {knowledgeSources, knowledgePieces} */, __assign(__assign({}, tools), { llm: llmToolsWithUsage }), __assign(__assign({}, options), { rootDirname: rootDirname, maxParallelCount: maxParallelCount /* <- TODO: [🪂] */, isVerbose: isVerbose }))];
|
|
5789
|
-
case
|
|
5790
|
-
partialknowledgePiecesPrepared =
|
|
5871
|
+
case 5:
|
|
5872
|
+
partialknowledgePiecesPrepared = _e.sent();
|
|
5791
5873
|
knowledgePiecesPrepared = partialknowledgePiecesPrepared.map(function (piece) { return (__assign(__assign({}, piece), { preparationIds: [/* TODO: [🧊] -> */ currentPreparation.id] })); });
|
|
5792
5874
|
return [4 /*yield*/, prepareTasks({
|
|
5793
5875
|
parameters: parameters,
|
|
@@ -5798,8 +5880,8 @@
|
|
|
5798
5880
|
maxParallelCount: maxParallelCount /* <- TODO: [🪂] */,
|
|
5799
5881
|
isVerbose: isVerbose,
|
|
5800
5882
|
})];
|
|
5801
|
-
case
|
|
5802
|
-
tasksPrepared = (
|
|
5883
|
+
case 6:
|
|
5884
|
+
tasksPrepared = (_e.sent()).tasksPrepared;
|
|
5803
5885
|
// ----- /Tasks preparation -----
|
|
5804
5886
|
// TODO: [😂] Use here all `AsyncHighLevelAbstraction`
|
|
5805
5887
|
// Note: Count total usage
|
|
@@ -5810,7 +5892,7 @@
|
|
|
5810
5892
|
order: ORDER_OF_PIPELINE_JSON,
|
|
5811
5893
|
value: __assign(__assign({}, pipeline), {
|
|
5812
5894
|
// <- TODO: Probbably deeply clone the pipeline because `$exportJson` freezes the subobjects
|
|
5813
|
-
knowledgeSources: knowledgeSourcesPrepared, knowledgePieces: knowledgePiecesPrepared, tasks: __spreadArray([], __read(tasksPrepared), false),
|
|
5895
|
+
title: title, knowledgeSources: knowledgeSourcesPrepared, knowledgePieces: knowledgePiecesPrepared, tasks: __spreadArray([], __read(tasksPrepared), false),
|
|
5814
5896
|
// <- TODO: [🪓] Here should be no need for spreading new array, just ` tasks: tasksPrepared`
|
|
5815
5897
|
personas: preparedPersonas, preparations: __spreadArray([], __read(preparations), false) }),
|
|
5816
5898
|
})];
|
|
@@ -5905,7 +5987,7 @@
|
|
|
5905
5987
|
if (sourceContent === '') {
|
|
5906
5988
|
throw new ParseError("Source is not defined");
|
|
5907
5989
|
}
|
|
5908
|
-
// TODO: [main]
|
|
5990
|
+
// TODO: [main] !!4 Following checks should be applied every link in the `sourceContent`
|
|
5909
5991
|
if (sourceContent.startsWith('http://')) {
|
|
5910
5992
|
throw new ParseError("Source is not secure");
|
|
5911
5993
|
}
|
|
@@ -6077,7 +6159,7 @@
|
|
|
6077
6159
|
expectResultingParameterName();
|
|
6078
6160
|
var parameter = $pipelineJson.parameters.find(function (param) { return param.name === $taskJson.resultingParameterName; });
|
|
6079
6161
|
if (parameter === undefined) {
|
|
6080
|
-
// TODO:
|
|
6162
|
+
// TODO: !!6 Change to logic error for higher level abstraction of chatbot to work
|
|
6081
6163
|
throw new ParseError("Parameter `{".concat($taskJson.resultingParameterName, "}` is not defined so can not define example value of it"));
|
|
6082
6164
|
}
|
|
6083
6165
|
parameter.exampleValues = parameter.exampleValues || [];
|
|
@@ -6088,7 +6170,7 @@
|
|
|
6088
6170
|
if (command.taskType === 'KNOWLEDGE') {
|
|
6089
6171
|
knowledgeCommandParser.$applyToPipelineJson({
|
|
6090
6172
|
type: 'KNOWLEDGE',
|
|
6091
|
-
sourceContent: $taskJson.content, // <- TODO: [🐝][main]
|
|
6173
|
+
sourceContent: $taskJson.content, // <- TODO: [🐝][main] !!3 Work with KNOWLEDGE which not referring to the source file or website, but its content itself
|
|
6092
6174
|
}, $pipelineJson);
|
|
6093
6175
|
$taskJson.isTask = false;
|
|
6094
6176
|
return;
|
|
@@ -6983,20 +7065,24 @@
|
|
|
6983
7065
|
*/
|
|
6984
7066
|
var GeneratorFormfactorDefinition = {
|
|
6985
7067
|
name: 'GENERATOR',
|
|
6986
|
-
description: "
|
|
7068
|
+
description: "Generates any kind (in HTML with possible scripts and css format) of content from input message",
|
|
6987
7069
|
documentationUrl: "https://github.com/webgptorg/promptbook/discussions/184",
|
|
6988
7070
|
pipelineInterface: {
|
|
6989
7071
|
inputParameters: [
|
|
6990
|
-
/* @@@ */
|
|
6991
7072
|
{
|
|
6992
|
-
name: '
|
|
6993
|
-
description:
|
|
7073
|
+
name: 'inputMessage',
|
|
7074
|
+
description: "Input message to be image made from",
|
|
6994
7075
|
isInput: true,
|
|
6995
7076
|
isOutput: false,
|
|
6996
7077
|
},
|
|
6997
7078
|
],
|
|
6998
7079
|
outputParameters: [
|
|
6999
|
-
|
|
7080
|
+
{
|
|
7081
|
+
name: 'result',
|
|
7082
|
+
description: "Result in HTML to be shown to user",
|
|
7083
|
+
isInput: false,
|
|
7084
|
+
isOutput: true,
|
|
7085
|
+
},
|
|
7000
7086
|
],
|
|
7001
7087
|
},
|
|
7002
7088
|
};
|
|
@@ -7028,6 +7114,35 @@
|
|
|
7028
7114
|
pipelineInterface: GENERIC_PIPELINE_INTERFACE,
|
|
7029
7115
|
};
|
|
7030
7116
|
|
|
7117
|
+
/**
|
|
7118
|
+
* Image generator is form of app that generates image from input message
|
|
7119
|
+
*
|
|
7120
|
+
* @public exported from `@promptbook/core`
|
|
7121
|
+
*/
|
|
7122
|
+
var ImageGeneratorFormfactorDefinition = {
|
|
7123
|
+
name: 'IMAGE_GENERATOR',
|
|
7124
|
+
description: "Generates prompt for image generation from input message",
|
|
7125
|
+
documentationUrl: "https://github.com/webgptorg/promptbook/discussions/184",
|
|
7126
|
+
pipelineInterface: {
|
|
7127
|
+
inputParameters: [
|
|
7128
|
+
{
|
|
7129
|
+
name: 'inputMessage',
|
|
7130
|
+
description: "Input message to be image made from",
|
|
7131
|
+
isInput: true,
|
|
7132
|
+
isOutput: false,
|
|
7133
|
+
},
|
|
7134
|
+
],
|
|
7135
|
+
outputParameters: [
|
|
7136
|
+
{
|
|
7137
|
+
name: 'prompt',
|
|
7138
|
+
description: "Prompt to be used for image generation",
|
|
7139
|
+
isInput: false,
|
|
7140
|
+
isOutput: true,
|
|
7141
|
+
},
|
|
7142
|
+
],
|
|
7143
|
+
},
|
|
7144
|
+
};
|
|
7145
|
+
|
|
7031
7146
|
/**
|
|
7032
7147
|
* Matcher is form of app that @@@
|
|
7033
7148
|
*
|
|
@@ -7126,6 +7241,7 @@
|
|
|
7126
7241
|
SheetsFormfactorDefinition,
|
|
7127
7242
|
MatcherFormfactorDefinition,
|
|
7128
7243
|
GeneratorFormfactorDefinition,
|
|
7244
|
+
ImageGeneratorFormfactorDefinition,
|
|
7129
7245
|
];
|
|
7130
7246
|
/**
|
|
7131
7247
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -7512,7 +7628,7 @@
|
|
|
7512
7628
|
* Note: `$` is used to indicate that this function mutates given `pipelineJson`
|
|
7513
7629
|
*/
|
|
7514
7630
|
$applyToPipelineJson: function (command, $pipelineJson) {
|
|
7515
|
-
// Note: [🍣] Do nothing, its application is implemented separately in `
|
|
7631
|
+
// Note: [🍣] Do nothing, its application is implemented separately in `parsePipeline`
|
|
7516
7632
|
},
|
|
7517
7633
|
/**
|
|
7518
7634
|
* Apply the PARAMETER command to the `pipelineJson`
|
|
@@ -7520,7 +7636,7 @@
|
|
|
7520
7636
|
* Note: `$` is used to indicate that this function mutates given `taskJson`
|
|
7521
7637
|
*/
|
|
7522
7638
|
$applyToTaskJson: function (command, $taskJson, $pipelineJson) {
|
|
7523
|
-
// Note: [🍣] Do nothing, its application is implemented separately in `
|
|
7639
|
+
// Note: [🍣] Do nothing, its application is implemented separately in `parsePipeline`
|
|
7524
7640
|
},
|
|
7525
7641
|
/**
|
|
7526
7642
|
* Converts the PARAMETER command back to string
|
|
@@ -8015,7 +8131,7 @@
|
|
|
8015
8131
|
instrumentCommandParser,
|
|
8016
8132
|
personaCommandParser,
|
|
8017
8133
|
foreachCommandParser,
|
|
8018
|
-
boilerplateCommandParser, // <- TODO:
|
|
8134
|
+
boilerplateCommandParser, // <- TODO: Only in development, remove in production
|
|
8019
8135
|
// <- 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
|
|
8020
8136
|
];
|
|
8021
8137
|
/**
|
|
@@ -8439,7 +8555,7 @@
|
|
|
8439
8555
|
isOutput: true,
|
|
8440
8556
|
exampleValues: ['Hello, I am a Pavol`s virtual avatar. How can I help you?'],
|
|
8441
8557
|
});
|
|
8442
|
-
// TODO:
|
|
8558
|
+
// TODO: Use spaceTrim in multiline strings
|
|
8443
8559
|
$pipelineJson.tasks.push({
|
|
8444
8560
|
taskType: 'PROMPT_TASK',
|
|
8445
8561
|
name: 'create-an-answer',
|
|
@@ -8447,8 +8563,11 @@
|
|
|
8447
8563
|
content: 'Write a response to the user message:\n\n**Question from user**\n\n> {userMessage}\n\n**Previous conversation**\n\n> {previousConversationSummary}',
|
|
8448
8564
|
resultingParameterName: 'chatbotResponse',
|
|
8449
8565
|
personaName: personaName,
|
|
8450
|
-
dependentParameterNames: [
|
|
8451
|
-
|
|
8566
|
+
dependentParameterNames: [
|
|
8567
|
+
'userMessage',
|
|
8568
|
+
'previousConversationSummary' /* TODO: [🧠][📛], 'knowledge'*/,
|
|
8569
|
+
],
|
|
8570
|
+
// TODO: [🧠][📛] preparedContent: '{content}\n\n## Knowledge\n\n{knowledge}',
|
|
8452
8571
|
}, {
|
|
8453
8572
|
taskType: 'PROMPT_TASK',
|
|
8454
8573
|
name: 'summarize-the-conversation',
|
|
@@ -8462,24 +8581,27 @@
|
|
|
8462
8581
|
max: 10,
|
|
8463
8582
|
},
|
|
8464
8583
|
},
|
|
8465
|
-
dependentParameterNames: ['userMessage', 'chatbotResponse' /*
|
|
8466
|
-
//
|
|
8584
|
+
dependentParameterNames: ['userMessage', 'chatbotResponse' /* TODO: [🧠][📛], 'knowledge'*/],
|
|
8585
|
+
// TODO: [🧠][📛] preparedContent: '{content}\n\n## Knowledge\n\n{knowledge}',
|
|
8467
8586
|
}, {
|
|
8468
8587
|
taskType: 'SIMPLE_TASK',
|
|
8469
8588
|
name: 'title',
|
|
8470
8589
|
title: 'Title',
|
|
8471
8590
|
content: '{conversationSummary}',
|
|
8472
8591
|
resultingParameterName: 'title',
|
|
8473
|
-
dependentParameterNames: ['conversationSummary' /*
|
|
8474
|
-
//
|
|
8592
|
+
dependentParameterNames: ['conversationSummary' /* TODO: [🧠][📛], 'knowledge'*/],
|
|
8593
|
+
// TODO: [🧠][📛] preparedContent: '{content}\n\n## Knowledge\n\n{knowledge}',
|
|
8475
8594
|
});
|
|
8476
8595
|
},
|
|
8477
8596
|
};
|
|
8597
|
+
/**
|
|
8598
|
+
* TODO: [🧠][📛] Should this be here?
|
|
8599
|
+
*/
|
|
8478
8600
|
|
|
8479
8601
|
/**
|
|
8480
8602
|
* All high-level abstractions
|
|
8481
8603
|
*
|
|
8482
|
-
* @private internal index of `
|
|
8604
|
+
* @private internal index of `parsePipeline` (= used for sync) and `preparePipeline` (= used for async)
|
|
8483
8605
|
*/
|
|
8484
8606
|
var HIGH_LEVEL_ABSTRACTIONS = [
|
|
8485
8607
|
ImplicitFormfactorHla,
|
|
@@ -8613,7 +8735,7 @@
|
|
|
8613
8735
|
return;
|
|
8614
8736
|
}
|
|
8615
8737
|
if (!section.startsWith('#')) {
|
|
8616
|
-
section = "# ".concat(
|
|
8738
|
+
section = "# ".concat(DEFAULT_BOOK_TITLE, "\n\n").concat(section);
|
|
8617
8739
|
}
|
|
8618
8740
|
sections.push(section);
|
|
8619
8741
|
buffer = [];
|
|
@@ -8668,7 +8790,7 @@
|
|
|
8668
8790
|
/**
|
|
8669
8791
|
* Normalizes the markdown by flattening the structure
|
|
8670
8792
|
*
|
|
8671
|
-
* - It always have h1 - if there is no h1 in the markdown, it will be added
|
|
8793
|
+
* - It always have h1 - if there is no h1 in the markdown, it will be added `DEFAULT_BOOK_TITLE`
|
|
8672
8794
|
* - All other headings are normalized to h2
|
|
8673
8795
|
*
|
|
8674
8796
|
* @public exported from `@promptbook/markdown-utils`
|
|
@@ -8677,7 +8799,7 @@
|
|
|
8677
8799
|
var e_1, _a;
|
|
8678
8800
|
var sections = splitMarkdownIntoSections(markdown);
|
|
8679
8801
|
if (sections.length === 0) {
|
|
8680
|
-
return "# ".concat(
|
|
8802
|
+
return "# ".concat(DEFAULT_BOOK_TITLE);
|
|
8681
8803
|
}
|
|
8682
8804
|
var flattenedMarkdown = '';
|
|
8683
8805
|
var parsedSections = sections.map(parseMarkdownSection);
|
|
@@ -8688,7 +8810,7 @@
|
|
|
8688
8810
|
}
|
|
8689
8811
|
else {
|
|
8690
8812
|
parsedSections.unshift(firstSection);
|
|
8691
|
-
flattenedMarkdown += "# ".concat(
|
|
8813
|
+
flattenedMarkdown += "# ".concat(DEFAULT_BOOK_TITLE) + "\n\n"; // <- [🧠] Maybe 3 new lines?
|
|
8692
8814
|
}
|
|
8693
8815
|
try {
|
|
8694
8816
|
for (var parsedSections_1 = __values(parsedSections), parsedSections_1_1 = parsedSections_1.next(); !parsedSections_1_1.done; parsedSections_1_1 = parsedSections_1.next()) {
|
|
@@ -8715,13 +8837,13 @@
|
|
|
8715
8837
|
*/
|
|
8716
8838
|
|
|
8717
8839
|
/**
|
|
8718
|
-
* Removes
|
|
8840
|
+
* Removes Markdown (or HTML) comments
|
|
8719
8841
|
*
|
|
8720
8842
|
* @param {string} content - The string to remove comments from.
|
|
8721
8843
|
* @returns {string} The input string with all comments removed.
|
|
8722
8844
|
* @public exported from `@promptbook/markdown-utils`
|
|
8723
8845
|
*/
|
|
8724
|
-
function
|
|
8846
|
+
function removeMarkdownComments(content) {
|
|
8725
8847
|
return spaceTrim.spaceTrim(content.replace(/<!--(.*?)-->/gs, ''));
|
|
8726
8848
|
}
|
|
8727
8849
|
|
|
@@ -8754,7 +8876,7 @@
|
|
|
8754
8876
|
*
|
|
8755
8877
|
* Note: There are 3 similar functions:
|
|
8756
8878
|
* - `compilePipeline` **(preferred)** - which propperly compiles the promptbook and use embedding for external knowledge
|
|
8757
|
-
* - `
|
|
8879
|
+
* - `parsePipeline` - use only if you need to compile promptbook synchronously and it contains NO external knowledge
|
|
8758
8880
|
* - `preparePipeline` - just one step in the compilation process
|
|
8759
8881
|
*
|
|
8760
8882
|
* Note: This function does not validate logic of the pipeline only the parsing
|
|
@@ -8765,10 +8887,10 @@
|
|
|
8765
8887
|
* @throws {ParseError} if the promptbook string is not valid
|
|
8766
8888
|
* @public exported from `@promptbook/core`
|
|
8767
8889
|
*/
|
|
8768
|
-
function
|
|
8890
|
+
function parsePipeline(pipelineString) {
|
|
8769
8891
|
var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e, e_6, _f;
|
|
8770
8892
|
var $pipelineJson = {
|
|
8771
|
-
title:
|
|
8893
|
+
title: DEFAULT_BOOK_TITLE,
|
|
8772
8894
|
parameters: [],
|
|
8773
8895
|
tasks: [],
|
|
8774
8896
|
knowledgeSources: [],
|
|
@@ -8779,7 +8901,7 @@
|
|
|
8779
8901
|
{
|
|
8780
8902
|
type: 'BOOK',
|
|
8781
8903
|
path: null,
|
|
8782
|
-
// <- TODO:
|
|
8904
|
+
// <- TODO: !!6 Pass here path of the file
|
|
8783
8905
|
content: pipelineString,
|
|
8784
8906
|
},
|
|
8785
8907
|
],
|
|
@@ -8797,18 +8919,44 @@
|
|
|
8797
8919
|
}
|
|
8798
8920
|
// =============================================================
|
|
8799
8921
|
// Note: 1️⃣ Parsing of the markdown into object
|
|
8922
|
+
// ==============
|
|
8923
|
+
// Note: 1️⃣◽1️⃣ Remove #!shebang and comments
|
|
8800
8924
|
if (pipelineString.startsWith('#!')) {
|
|
8801
8925
|
var _g = __read(pipelineString.split('\n')), shebangLine_1 = _g[0], restLines = _g.slice(1);
|
|
8802
8926
|
if (!(shebangLine_1 || '').includes('ptbk')) {
|
|
8803
8927
|
throw new ParseError(spaceTrim.spaceTrim(function (block) { return "\n It seems that you try to parse a book file which has non-standard shebang line for book files:\n Shebang line must contain 'ptbk'\n\n You have:\n ".concat(block(shebangLine_1 || '(empty line)'), "\n\n It should look like this:\n #!/usr/bin/env ptbk\n\n ").concat(block(getPipelineIdentification()), "\n "); }));
|
|
8804
8928
|
}
|
|
8805
|
-
pipelineString = restLines.join('\n');
|
|
8806
|
-
}
|
|
8807
|
-
pipelineString =
|
|
8929
|
+
pipelineString = validatePipelineString(restLines.join('\n'));
|
|
8930
|
+
}
|
|
8931
|
+
pipelineString = removeMarkdownComments(pipelineString);
|
|
8932
|
+
pipelineString = spaceTrim.spaceTrim(pipelineString);
|
|
8933
|
+
// <- TODO: [😧] `spaceTrim` should preserve discriminated type *(or at lease `PipelineString`)*
|
|
8934
|
+
// ==============
|
|
8935
|
+
// Note: 1️⃣◽2️⃣ Process flat pipeline
|
|
8936
|
+
var isMarkdownBeginningWithHeadline = pipelineString.startsWith('# ');
|
|
8937
|
+
var isLastLineReturnStatement = pipelineString.split('\n').pop().split('`').join('').startsWith('->');
|
|
8938
|
+
// TODO: Also (double)check
|
|
8939
|
+
// > const usedCommands
|
|
8940
|
+
// > const isBlocksUsed
|
|
8941
|
+
// > const returnStatementCount
|
|
8942
|
+
var isFlatPipeline = !isMarkdownBeginningWithHeadline && isLastLineReturnStatement;
|
|
8943
|
+
// console.log({ isMarkdownBeginningWithHeadline, isLastLineReturnStatement, isFlatPipeline });
|
|
8944
|
+
if (isFlatPipeline) {
|
|
8945
|
+
var pipelineStringLines = pipelineString.split('\n');
|
|
8946
|
+
var returnStatement_1 = pipelineStringLines.pop();
|
|
8947
|
+
var prompt_1 = spaceTrim.spaceTrim(pipelineStringLines.join('\n'));
|
|
8948
|
+
pipelineString = validatePipelineString(spaceTrim.spaceTrim(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 "); }));
|
|
8949
|
+
// <- TODO: Maybe use book` notation
|
|
8950
|
+
// console.log(pipelineString);
|
|
8951
|
+
}
|
|
8952
|
+
// ==============
|
|
8953
|
+
// Note: 1️⃣◽3️⃣ Parse the markdown
|
|
8808
8954
|
pipelineString = flattenMarkdown(pipelineString) /* <- Note: [🥞] */;
|
|
8809
8955
|
pipelineString = pipelineString.replaceAll(/`\{(?<parameterName>[a-z0-9_]+)\}`/gi, '{$<parameterName>}');
|
|
8810
8956
|
pipelineString = pipelineString.replaceAll(/`->\s+\{(?<parameterName>[a-z0-9_]+)\}`/gi, '-> {$<parameterName>}');
|
|
8811
8957
|
var _h = __read(splitMarkdownIntoSections(pipelineString).map(parseMarkdownSection)), pipelineHead = _h[0], pipelineSections = _h.slice(1); /* <- Note: [🥞] */
|
|
8958
|
+
// ==============
|
|
8959
|
+
// Note: 1️⃣◽4️⃣ Check markdown structure
|
|
8812
8960
|
if (pipelineHead === undefined) {
|
|
8813
8961
|
throw new UnexpectedError(spaceTrim.spaceTrim(function (block) { return "\n Pipeline head is not defined\n\n ".concat(block(getPipelineIdentification()), "\n\n This should never happen, because the pipeline already flattened\n "); }));
|
|
8814
8962
|
}
|
|
@@ -9192,14 +9340,14 @@
|
|
|
9192
9340
|
// =============================================================
|
|
9193
9341
|
return exportJson({
|
|
9194
9342
|
name: 'pipelineJson',
|
|
9195
|
-
message: "Result of `
|
|
9343
|
+
message: "Result of `parsePipeline`",
|
|
9196
9344
|
order: ORDER_OF_PIPELINE_JSON,
|
|
9197
9345
|
value: __assign({ formfactorName: 'GENERIC' }, $pipelineJson),
|
|
9198
9346
|
});
|
|
9199
9347
|
}
|
|
9200
9348
|
/**
|
|
9201
9349
|
* TODO: [🧠] Maybe more things here can be refactored as high-level abstractions
|
|
9202
|
-
* TODO: [main]
|
|
9350
|
+
* TODO: [main] !!4 Warn if used only sync version
|
|
9203
9351
|
* TODO: [🚞] Report here line/column of error
|
|
9204
9352
|
* TODO: Use spaceTrim more effectively
|
|
9205
9353
|
* TODO: [🧠] Parameter flags - isInput, isOutput, isInternal
|
|
@@ -9212,10 +9360,7 @@
|
|
|
9212
9360
|
/**
|
|
9213
9361
|
* Compile pipeline from string (markdown) format to JSON format
|
|
9214
9362
|
*
|
|
9215
|
-
*
|
|
9216
|
-
* - `compilePipeline` **(preferred)** - which propperly compiles the promptbook and use embedding for external knowledge
|
|
9217
|
-
* - `precompilePipeline` - use only if you need to compile promptbook synchronously and it contains NO external knowledge
|
|
9218
|
-
* - `preparePipeline` - just one step in the compilation process
|
|
9363
|
+
* @see https://github.com/webgptorg/promptbook/discussions/196
|
|
9219
9364
|
*
|
|
9220
9365
|
* Note: This function does not validate logic of the pipeline only the parsing
|
|
9221
9366
|
* Note: This function acts as compilation process
|
|
@@ -9233,7 +9378,7 @@
|
|
|
9233
9378
|
return __generator(this, function (_a) {
|
|
9234
9379
|
switch (_a.label) {
|
|
9235
9380
|
case 0:
|
|
9236
|
-
pipelineJson =
|
|
9381
|
+
pipelineJson = parsePipeline(pipelineString);
|
|
9237
9382
|
if (!(tools !== undefined && tools.llm !== undefined)) return [3 /*break*/, 2];
|
|
9238
9383
|
return [4 /*yield*/, preparePipeline(pipelineJson, tools, options || {
|
|
9239
9384
|
rootDirname: null,
|
|
@@ -9242,7 +9387,7 @@
|
|
|
9242
9387
|
pipelineJson = _a.sent();
|
|
9243
9388
|
_a.label = 2;
|
|
9244
9389
|
case 2:
|
|
9245
|
-
// Note: No need to use `$exportJson` because `
|
|
9390
|
+
// Note: No need to use `$exportJson` because `parsePipeline` and `preparePipeline` already do that
|
|
9246
9391
|
return [2 /*return*/, pipelineJson];
|
|
9247
9392
|
}
|
|
9248
9393
|
});
|
|
@@ -9593,6 +9738,25 @@
|
|
|
9593
9738
|
* TODO: [®] DRY Register logic
|
|
9594
9739
|
*/
|
|
9595
9740
|
|
|
9741
|
+
/**
|
|
9742
|
+
* Determines if the given path is a root path.
|
|
9743
|
+
*
|
|
9744
|
+
* Note: This does not check if the file exists only if the path is valid
|
|
9745
|
+
* @public exported from `@promptbook/utils`
|
|
9746
|
+
*/
|
|
9747
|
+
function isRootPath(value) {
|
|
9748
|
+
if (value === '/') {
|
|
9749
|
+
return true;
|
|
9750
|
+
}
|
|
9751
|
+
if (/^[A-Z]:\\$/i.test(value)) {
|
|
9752
|
+
return true;
|
|
9753
|
+
}
|
|
9754
|
+
return false;
|
|
9755
|
+
}
|
|
9756
|
+
/**
|
|
9757
|
+
* TODO: [🍏] Make for MacOS paths
|
|
9758
|
+
*/
|
|
9759
|
+
|
|
9596
9760
|
/**
|
|
9597
9761
|
* @@@
|
|
9598
9762
|
*
|
|
@@ -9607,17 +9771,45 @@
|
|
|
9607
9771
|
* @public exported from `@promptbook/node`
|
|
9608
9772
|
*/
|
|
9609
9773
|
function $provideLlmToolsConfigurationFromEnv() {
|
|
9610
|
-
|
|
9611
|
-
|
|
9612
|
-
|
|
9613
|
-
|
|
9614
|
-
|
|
9615
|
-
|
|
9616
|
-
|
|
9617
|
-
|
|
9618
|
-
|
|
9619
|
-
|
|
9620
|
-
|
|
9774
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
9775
|
+
var rootDirname, i, envFilename, llmToolsConfiguration;
|
|
9776
|
+
return __generator(this, function (_a) {
|
|
9777
|
+
switch (_a.label) {
|
|
9778
|
+
case 0:
|
|
9779
|
+
if (!$isRunningInNode()) {
|
|
9780
|
+
throw new EnvironmentMismatchError('Function `$provideLlmToolsFromEnv` works only in Node.js environment');
|
|
9781
|
+
}
|
|
9782
|
+
rootDirname = process.cwd();
|
|
9783
|
+
i = 0;
|
|
9784
|
+
_a.label = 1;
|
|
9785
|
+
case 1:
|
|
9786
|
+
if (!(i < LOOP_LIMIT)) return [3 /*break*/, 4];
|
|
9787
|
+
envFilename = path.join(rootDirname, '.env' /* <- TODO: [🕝] Make here more candidates */);
|
|
9788
|
+
return [4 /*yield*/, isFileExisting(envFilename, $provideFilesystemForNode())];
|
|
9789
|
+
case 2:
|
|
9790
|
+
// console.log({ rootDirname, envFilename });
|
|
9791
|
+
if (_a.sent()) {
|
|
9792
|
+
dotenv__namespace.config({ path: envFilename });
|
|
9793
|
+
return [3 /*break*/, 4];
|
|
9794
|
+
}
|
|
9795
|
+
if (isRootPath(rootDirname)) {
|
|
9796
|
+
return [3 /*break*/, 4];
|
|
9797
|
+
}
|
|
9798
|
+
// Note: If the directory does not exist, try the parent directory
|
|
9799
|
+
rootDirname = path.join(rootDirname, '..');
|
|
9800
|
+
_a.label = 3;
|
|
9801
|
+
case 3:
|
|
9802
|
+
i++;
|
|
9803
|
+
return [3 /*break*/, 1];
|
|
9804
|
+
case 4:
|
|
9805
|
+
llmToolsConfiguration = $llmToolsMetadataRegister
|
|
9806
|
+
.list()
|
|
9807
|
+
.map(function (metadata) { return metadata.createConfigurationFromEnv(process.env); })
|
|
9808
|
+
.filter(function (configuration) { return configuration !== null; });
|
|
9809
|
+
return [2 /*return*/, llmToolsConfiguration];
|
|
9810
|
+
}
|
|
9811
|
+
});
|
|
9812
|
+
});
|
|
9621
9813
|
}
|
|
9622
9814
|
/**
|
|
9623
9815
|
* TODO: [🧠][🪁] Maybe do allow to do auto-install if package not registered and not found
|
|
@@ -9840,15 +10032,28 @@
|
|
|
9840
10032
|
*/
|
|
9841
10033
|
function $provideLlmToolsFromEnv(options) {
|
|
9842
10034
|
if (options === void 0) { options = {}; }
|
|
9843
|
-
|
|
9844
|
-
|
|
9845
|
-
|
|
9846
|
-
|
|
9847
|
-
|
|
9848
|
-
|
|
9849
|
-
|
|
9850
|
-
|
|
9851
|
-
|
|
10035
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
10036
|
+
var configuration;
|
|
10037
|
+
return __generator(this, function (_a) {
|
|
10038
|
+
switch (_a.label) {
|
|
10039
|
+
case 0:
|
|
10040
|
+
if (!$isRunningInNode()) {
|
|
10041
|
+
throw new EnvironmentMismatchError('Function `$provideLlmToolsFromEnv` works only in Node.js environment');
|
|
10042
|
+
}
|
|
10043
|
+
return [4 /*yield*/, $provideLlmToolsConfigurationFromEnv()];
|
|
10044
|
+
case 1:
|
|
10045
|
+
configuration = _a.sent();
|
|
10046
|
+
if (configuration.length === 0) {
|
|
10047
|
+
if ($llmToolsMetadataRegister.list().length === 0) {
|
|
10048
|
+
throw new UnexpectedError(spaceTrim__default["default"](function (block) { return "\n No LLM tools registered, this is probably a bug in the Promptbook library\n\n ".concat(block($registeredLlmToolsMessage()), "}\n "); }));
|
|
10049
|
+
}
|
|
10050
|
+
// TODO: [🥃]
|
|
10051
|
+
throw new Error(spaceTrim__default["default"](function (block) { return "\n No LLM tools found in the environment\n\n ".concat(block($registeredLlmToolsMessage()), "}\n "); }));
|
|
10052
|
+
}
|
|
10053
|
+
return [2 /*return*/, createLlmToolsFromConfiguration(configuration, options)];
|
|
10054
|
+
}
|
|
10055
|
+
});
|
|
10056
|
+
});
|
|
9852
10057
|
}
|
|
9853
10058
|
/**
|
|
9854
10059
|
* TODO: @@@ write `$provideLlmToolsFromEnv` vs `$provideLlmToolsConfigurationFromEnv` vs `createLlmToolsFromConfiguration`
|
|
@@ -9917,23 +10122,31 @@
|
|
|
9917
10122
|
*/
|
|
9918
10123
|
|
|
9919
10124
|
/**
|
|
9920
|
-
*
|
|
10125
|
+
* Detects if the code is running in a browser environment in main thread (Not in a web worker)
|
|
9921
10126
|
*
|
|
9922
|
-
*
|
|
10127
|
+
* Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
|
|
9923
10128
|
*
|
|
9924
|
-
*
|
|
9925
|
-
|
|
9926
|
-
|
|
9927
|
-
|
|
9928
|
-
|
|
10129
|
+
* @public exported from `@promptbook/utils`
|
|
10130
|
+
*/
|
|
10131
|
+
new Function("\n try {\n return this === window;\n } catch (e) {\n return false;\n }\n");
|
|
10132
|
+
|
|
10133
|
+
/**
|
|
10134
|
+
* Detects if the code is running in jest environment
|
|
9929
10135
|
*
|
|
9930
|
-
*
|
|
9931
|
-
*
|
|
10136
|
+
* Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
|
|
10137
|
+
*
|
|
10138
|
+
* @public exported from `@promptbook/utils`
|
|
9932
10139
|
*/
|
|
9933
|
-
|
|
9934
|
-
|
|
9935
|
-
|
|
9936
|
-
|
|
10140
|
+
new Function("\n try {\n return process.env.JEST_WORKER_ID !== undefined;\n } catch (e) {\n return false;\n }\n");
|
|
10141
|
+
|
|
10142
|
+
/**
|
|
10143
|
+
* Detects if the code is running in a web worker
|
|
10144
|
+
*
|
|
10145
|
+
* Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
|
|
10146
|
+
*
|
|
10147
|
+
* @public exported from `@promptbook/utils`
|
|
10148
|
+
*/
|
|
10149
|
+
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");
|
|
9937
10150
|
|
|
9938
10151
|
/**
|
|
9939
10152
|
* Makes first letter of a string uppercase
|
|
@@ -9944,6 +10157,21 @@
|
|
|
9944
10157
|
return word.substring(0, 1).toLowerCase() + word.substring(1);
|
|
9945
10158
|
}
|
|
9946
10159
|
|
|
10160
|
+
/**
|
|
10161
|
+
* Parses keywords from a string
|
|
10162
|
+
*
|
|
10163
|
+
* @param {string} input
|
|
10164
|
+
* @returns {Set} of keywords without diacritics in lowercase
|
|
10165
|
+
* @public exported from `@promptbook/utils`
|
|
10166
|
+
*/
|
|
10167
|
+
function parseKeywordsFromString(input) {
|
|
10168
|
+
var keywords = normalizeTo_SCREAMING_CASE(removeDiacritics(input))
|
|
10169
|
+
.toLowerCase()
|
|
10170
|
+
.split(/[^a-z0-9]+/gs)
|
|
10171
|
+
.filter(function (value) { return value; });
|
|
10172
|
+
return new Set(keywords);
|
|
10173
|
+
}
|
|
10174
|
+
|
|
9947
10175
|
/**
|
|
9948
10176
|
* @@@
|
|
9949
10177
|
*
|
|
@@ -9997,20 +10225,39 @@
|
|
|
9997
10225
|
return sentence.replace(/\s+/gs, ' ').trim();
|
|
9998
10226
|
}
|
|
9999
10227
|
|
|
10228
|
+
// <- TODO: Auto convert to type `import { ... } from 'type-fest';`
|
|
10000
10229
|
/**
|
|
10001
|
-
*
|
|
10230
|
+
* Tests if the value is [🚉] serializable as JSON
|
|
10231
|
+
*
|
|
10232
|
+
* - Almost all primitives are serializable BUT:
|
|
10233
|
+
* - `undefined` is not serializable
|
|
10234
|
+
* - `NaN` is not serializable
|
|
10235
|
+
* - Objects and arrays are serializable if all their properties are serializable
|
|
10236
|
+
* - Functions are not serializable
|
|
10237
|
+
* - Circular references are not serializable
|
|
10238
|
+
* - `Date` objects are not serializable
|
|
10239
|
+
* - `Map` and `Set` objects are not serializable
|
|
10240
|
+
* - `RegExp` objects are not serializable
|
|
10241
|
+
* - `Error` objects are not serializable
|
|
10242
|
+
* - `Symbol` objects are not serializable
|
|
10243
|
+
* - And much more...
|
|
10244
|
+
*
|
|
10002
10245
|
*
|
|
10003
|
-
* @param {string} input
|
|
10004
|
-
* @returns {Set} of keywords without diacritics in lowercase
|
|
10005
10246
|
* @public exported from `@promptbook/utils`
|
|
10006
10247
|
*/
|
|
10007
|
-
function
|
|
10008
|
-
|
|
10009
|
-
|
|
10010
|
-
|
|
10011
|
-
|
|
10012
|
-
|
|
10248
|
+
function isSerializableAsJson(value) {
|
|
10249
|
+
try {
|
|
10250
|
+
checkSerializableAsJson({ value: value });
|
|
10251
|
+
return true;
|
|
10252
|
+
}
|
|
10253
|
+
catch (error) {
|
|
10254
|
+
return false;
|
|
10255
|
+
}
|
|
10013
10256
|
}
|
|
10257
|
+
/**
|
|
10258
|
+
* TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
10259
|
+
* TODO: [🧠][💺] Can be done this on type-level?
|
|
10260
|
+
*/
|
|
10014
10261
|
|
|
10015
10262
|
/**
|
|
10016
10263
|
* Function trimCodeBlock will trim starting and ending code block from the string if it is present.
|
|
@@ -10118,6 +10365,25 @@
|
|
|
10118
10365
|
* TODO: [🧠] Should this also unwrap the (parenthesis)
|
|
10119
10366
|
*/
|
|
10120
10367
|
|
|
10368
|
+
/**
|
|
10369
|
+
* Extracts code block from markdown.
|
|
10370
|
+
*
|
|
10371
|
+
* - When there are multiple or no code blocks the function throws a `ParseError`
|
|
10372
|
+
*
|
|
10373
|
+
* Note: There are multiple simmilar function:
|
|
10374
|
+
* - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
|
|
10375
|
+
* - `extractJsonBlock` extracts exactly one valid JSON code block
|
|
10376
|
+
* - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
|
|
10377
|
+
* - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
|
|
10378
|
+
*
|
|
10379
|
+
* @public exported from `@promptbook/markdown-utils`
|
|
10380
|
+
* @throws {ParseError} if there is not exactly one code block in the markdown
|
|
10381
|
+
*/
|
|
10382
|
+
function extractBlock(markdown) {
|
|
10383
|
+
var content = extractOneBlockFromMarkdown(markdown).content;
|
|
10384
|
+
return content;
|
|
10385
|
+
}
|
|
10386
|
+
|
|
10121
10387
|
/**
|
|
10122
10388
|
* Does nothing, but preserves the function in the bundle
|
|
10123
10389
|
* Compiler is tricked into thinking the function is used
|
|
@@ -10152,36 +10418,9 @@
|
|
|
10152
10418
|
}); })();
|
|
10153
10419
|
}
|
|
10154
10420
|
/**
|
|
10155
|
-
* TODO:
|
|
10156
|
-
|
|
10157
|
-
|
|
10158
|
-
/**
|
|
10159
|
-
* Converts anything to string that can be used for debugging and logging
|
|
10160
|
-
*
|
|
10161
|
-
* @param value String value for logging
|
|
10162
|
-
* @private internal util
|
|
10421
|
+
* TODO: Probbably remove in favour of `keepImported`
|
|
10422
|
+
* TODO: [1] This maybe does memory leak
|
|
10163
10423
|
*/
|
|
10164
|
-
function unknownToString(value) {
|
|
10165
|
-
if (value === undefined) {
|
|
10166
|
-
return 'undefined';
|
|
10167
|
-
}
|
|
10168
|
-
else if (value === null) {
|
|
10169
|
-
return 'null';
|
|
10170
|
-
}
|
|
10171
|
-
else if (['number', 'string', 'boolean'].includes(typeof value)) {
|
|
10172
|
-
return typeof value + ' ' + value.toString();
|
|
10173
|
-
}
|
|
10174
|
-
else if (typeof value === 'object' && Array.isArray(value)) {
|
|
10175
|
-
return 'array containing [' + value.map(function (item) { return unknownToString(item); }).join(', ') + ']';
|
|
10176
|
-
}
|
|
10177
|
-
else if (typeof value === 'object') {
|
|
10178
|
-
// TODO: Maybe serialize the object
|
|
10179
|
-
return 'object';
|
|
10180
|
-
}
|
|
10181
|
-
else {
|
|
10182
|
-
return 'unknown (Search in promptbook code for [🔹])';
|
|
10183
|
-
}
|
|
10184
|
-
}
|
|
10185
10424
|
|
|
10186
10425
|
/**
|
|
10187
10426
|
* ScriptExecutionTools for JavaScript implemented via eval
|
|
@@ -10312,7 +10551,7 @@
|
|
|
10312
10551
|
case 2:
|
|
10313
10552
|
result = _a.sent();
|
|
10314
10553
|
if (typeof result !== 'string') {
|
|
10315
|
-
throw new PipelineExecutionError("Script must return a string, but returned ".concat(
|
|
10554
|
+
throw new PipelineExecutionError("Script must return a string, but returned ".concat(valueToString(result)));
|
|
10316
10555
|
}
|
|
10317
10556
|
return [3 /*break*/, 4];
|
|
10318
10557
|
case 3:
|
|
@@ -10339,7 +10578,7 @@
|
|
|
10339
10578
|
throw error_1;
|
|
10340
10579
|
case 4:
|
|
10341
10580
|
if (typeof result !== 'string') {
|
|
10342
|
-
throw new PipelineExecutionError("Script must return a string, but ".concat(
|
|
10581
|
+
throw new PipelineExecutionError("Script must return a string, but ".concat(valueToString(result)));
|
|
10343
10582
|
}
|
|
10344
10583
|
return [2 /*return*/, result];
|
|
10345
10584
|
}
|
|
@@ -10379,9 +10618,11 @@
|
|
|
10379
10618
|
throw new EnvironmentMismatchError('Function `$getExecutionToolsForNode` works only in Node.js environment');
|
|
10380
10619
|
}
|
|
10381
10620
|
fs = $provideFilesystemForNode();
|
|
10382
|
-
|
|
10383
|
-
return [4 /*yield*/, $provideExecutablesForNode(options)];
|
|
10621
|
+
return [4 /*yield*/, $provideLlmToolsFromEnv(options)];
|
|
10384
10622
|
case 1:
|
|
10623
|
+
llm = _b.sent();
|
|
10624
|
+
return [4 /*yield*/, $provideExecutablesForNode(options)];
|
|
10625
|
+
case 2:
|
|
10385
10626
|
executables = _b.sent();
|
|
10386
10627
|
_a = {
|
|
10387
10628
|
llm: llm,
|
|
@@ -10389,7 +10630,7 @@
|
|
|
10389
10630
|
executables: executables
|
|
10390
10631
|
};
|
|
10391
10632
|
return [4 /*yield*/, $provideScrapersForNode({ fs: fs, llm: llm, executables: executables }, options)];
|
|
10392
|
-
case
|
|
10633
|
+
case 3:
|
|
10393
10634
|
tools = (_a.scrapers = _b.sent(),
|
|
10394
10635
|
_a.script = [new JavascriptExecutionTools(options)],
|
|
10395
10636
|
_a);
|
|
@@ -10612,7 +10853,7 @@
|
|
|
10612
10853
|
*/
|
|
10613
10854
|
function createCollectionFromDirectory(path$1, tools, options) {
|
|
10614
10855
|
return __awaiter(this, void 0, void 0, function () {
|
|
10615
|
-
var
|
|
10856
|
+
var madeLibraryFilePath, _a, _b, isRecursive, _c, isVerbose, _d, isLazyLoaded, _e, isCrashedOnError, rootUrl, collection;
|
|
10616
10857
|
var _this = this;
|
|
10617
10858
|
return __generator(this, function (_f) {
|
|
10618
10859
|
switch (_f.label) {
|
|
@@ -10627,18 +10868,18 @@
|
|
|
10627
10868
|
throw new EnvironmentMismatchError('Can not create collection without filesystem tools');
|
|
10628
10869
|
// <- TODO: [🧠] What is the best error type here`
|
|
10629
10870
|
}
|
|
10630
|
-
|
|
10871
|
+
madeLibraryFilePath = path.join(path$1, "".concat(DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME
|
|
10631
10872
|
// <- TODO: [🦒] Allow to override (pass different value into the function)
|
|
10632
10873
|
, ".json"));
|
|
10633
|
-
return [4 /*yield*/, isFileExisting(
|
|
10874
|
+
return [4 /*yield*/, isFileExisting(madeLibraryFilePath, tools.fs)];
|
|
10634
10875
|
case 3:
|
|
10635
10876
|
if (!(_f.sent())) ;
|
|
10636
10877
|
else {
|
|
10637
|
-
colors__default["default"].green("(In future, not implemented yet) Using your compiled pipeline collection ".concat(
|
|
10638
|
-
// TODO:
|
|
10878
|
+
colors__default["default"].green("(In future, not implemented yet) Using your compiled pipeline collection ".concat(madeLibraryFilePath));
|
|
10879
|
+
// TODO: Implement;
|
|
10639
10880
|
// TODO: [🌗]
|
|
10640
10881
|
}
|
|
10641
|
-
_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;
|
|
10882
|
+
_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;
|
|
10642
10883
|
collection = createCollectionFromPromise(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
10643
10884
|
var fileNames, collection, _loop_1, fileNames_1, fileNames_1_1, fileName, e_1_1;
|
|
10644
10885
|
var e_1, _a;
|
|
@@ -10664,34 +10905,35 @@
|
|
|
10664
10905
|
});
|
|
10665
10906
|
collection = new Map();
|
|
10666
10907
|
_loop_1 = function (fileName) {
|
|
10667
|
-
var sourceFile, rootDirname, pipeline, pipelineString, _c, _d, existing, error_1, wrappedErrorMessage;
|
|
10668
|
-
return __generator(this, function (
|
|
10669
|
-
switch (
|
|
10908
|
+
var sourceFile, rootDirname, pipeline, pipelineString, _c, _d, _e, pipelineUrl, existing, error_1, wrappedErrorMessage;
|
|
10909
|
+
return __generator(this, function (_f) {
|
|
10910
|
+
switch (_f.label) {
|
|
10670
10911
|
case 0:
|
|
10671
10912
|
sourceFile = './' + fileName.split('\\').join('/');
|
|
10672
10913
|
rootDirname = path.dirname(sourceFile).split('\\').join('/');
|
|
10673
|
-
|
|
10914
|
+
_f.label = 1;
|
|
10674
10915
|
case 1:
|
|
10675
|
-
|
|
10916
|
+
_f.trys.push([1, 8, , 9]);
|
|
10676
10917
|
pipeline = null;
|
|
10677
10918
|
if (!fileName.endsWith('.book.md')) return [3 /*break*/, 4];
|
|
10919
|
+
_c = validatePipelineString;
|
|
10678
10920
|
return [4 /*yield*/, promises.readFile(fileName, 'utf-8')];
|
|
10679
10921
|
case 2:
|
|
10680
|
-
pipelineString = (
|
|
10922
|
+
pipelineString = _c.apply(void 0, [_f.sent()]);
|
|
10681
10923
|
return [4 /*yield*/, compilePipeline(pipelineString, tools, {
|
|
10682
10924
|
rootDirname: rootDirname,
|
|
10683
10925
|
})];
|
|
10684
10926
|
case 3:
|
|
10685
|
-
pipeline =
|
|
10927
|
+
pipeline = _f.sent();
|
|
10686
10928
|
pipeline = __assign(__assign({}, pipeline), { sourceFile: sourceFile });
|
|
10687
10929
|
return [3 /*break*/, 7];
|
|
10688
10930
|
case 4:
|
|
10689
10931
|
if (!fileName.endsWith('.book.json')) return [3 /*break*/, 6];
|
|
10690
|
-
|
|
10932
|
+
_e = (_d = JSON).parse;
|
|
10691
10933
|
return [4 /*yield*/, promises.readFile(fileName, 'utf-8')];
|
|
10692
10934
|
case 5:
|
|
10693
10935
|
// TODO: Handle non-valid JSON files
|
|
10694
|
-
pipeline =
|
|
10936
|
+
pipeline = _e.apply(_d, [_f.sent()]);
|
|
10695
10937
|
// TODO: [🌗]
|
|
10696
10938
|
pipeline = __assign(__assign({}, pipeline), { sourceFile: sourceFile });
|
|
10697
10939
|
return [3 /*break*/, 7];
|
|
@@ -10699,10 +10941,24 @@
|
|
|
10699
10941
|
if (isVerbose) {
|
|
10700
10942
|
console.info(colors__default["default"].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")));
|
|
10701
10943
|
}
|
|
10702
|
-
|
|
10944
|
+
_f.label = 7;
|
|
10703
10945
|
case 7:
|
|
10704
10946
|
// ---
|
|
10705
10947
|
if (pipeline !== null) {
|
|
10948
|
+
if (rootUrl !== undefined) {
|
|
10949
|
+
if (pipeline.pipelineUrl === undefined) {
|
|
10950
|
+
pipelineUrl = rootUrl + '/' + fileName.split('\\').join('/');
|
|
10951
|
+
if (isVerbose) {
|
|
10952
|
+
console.info(colors__default["default"].yellow("Implicitly set pipeline URL to ".concat(pipelineUrl, " from ").concat(fileName
|
|
10953
|
+
.split('\\')
|
|
10954
|
+
.join('/'))));
|
|
10955
|
+
}
|
|
10956
|
+
pipeline = __assign(__assign({}, pipeline), { pipelineUrl: pipelineUrl });
|
|
10957
|
+
}
|
|
10958
|
+
else if (!pipeline.pipelineUrl.startsWith(rootUrl)) {
|
|
10959
|
+
throw new PipelineUrlError(spaceTrim__default["default"]("\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 ")));
|
|
10960
|
+
}
|
|
10961
|
+
}
|
|
10706
10962
|
// TODO: [👠] DRY
|
|
10707
10963
|
if (pipeline.pipelineUrl === undefined) {
|
|
10708
10964
|
if (isVerbose) {
|
|
@@ -10734,17 +10990,17 @@
|
|
|
10734
10990
|
}
|
|
10735
10991
|
else {
|
|
10736
10992
|
existing = collection.get(pipeline.pipelineUrl);
|
|
10737
|
-
throw new PipelineUrlError(spaceTrim__default["default"]("\n Pipeline with URL
|
|
10993
|
+
throw new PipelineUrlError(spaceTrim__default["default"]("\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 ")));
|
|
10738
10994
|
}
|
|
10739
10995
|
}
|
|
10740
10996
|
}
|
|
10741
10997
|
return [3 /*break*/, 9];
|
|
10742
10998
|
case 8:
|
|
10743
|
-
error_1 =
|
|
10999
|
+
error_1 = _f.sent();
|
|
10744
11000
|
if (!(error_1 instanceof Error)) {
|
|
10745
11001
|
throw error_1;
|
|
10746
11002
|
}
|
|
10747
|
-
wrappedErrorMessage = spaceTrim__default["default"](function (block) { return "\n
|
|
11003
|
+
wrappedErrorMessage = spaceTrim__default["default"](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';
|
|
10748
11004
|
if (isCrashedOnError) {
|
|
10749
11005
|
throw new CollectionError(wrappedErrorMessage);
|
|
10750
11006
|
}
|
|
@@ -10800,40 +11056,6 @@
|
|
|
10800
11056
|
* TODO: Maybe move from `@promptbook/node` to `@promptbook/core` as we removes direct dependency on `fs`
|
|
10801
11057
|
*/
|
|
10802
11058
|
|
|
10803
|
-
// <- TODO: !!!!!!! Auto convert to type `import { ... } from 'type-fest';`
|
|
10804
|
-
/**
|
|
10805
|
-
* Tests if the value is [🚉] serializable as JSON
|
|
10806
|
-
*
|
|
10807
|
-
* - Almost all primitives are serializable BUT:
|
|
10808
|
-
* - `undefined` is not serializable
|
|
10809
|
-
* - `NaN` is not serializable
|
|
10810
|
-
* - Objects and arrays are serializable if all their properties are serializable
|
|
10811
|
-
* - Functions are not serializable
|
|
10812
|
-
* - Circular references are not serializable
|
|
10813
|
-
* - `Date` objects are not serializable
|
|
10814
|
-
* - `Map` and `Set` objects are not serializable
|
|
10815
|
-
* - `RegExp` objects are not serializable
|
|
10816
|
-
* - `Error` objects are not serializable
|
|
10817
|
-
* - `Symbol` objects are not serializable
|
|
10818
|
-
* - And much more...
|
|
10819
|
-
*
|
|
10820
|
-
*
|
|
10821
|
-
* @public exported from `@promptbook/utils`
|
|
10822
|
-
*/
|
|
10823
|
-
function isSerializableAsJson(value) {
|
|
10824
|
-
try {
|
|
10825
|
-
checkSerializableAsJson({ value: value });
|
|
10826
|
-
return true;
|
|
10827
|
-
}
|
|
10828
|
-
catch (error) {
|
|
10829
|
-
return false;
|
|
10830
|
-
}
|
|
10831
|
-
}
|
|
10832
|
-
/**
|
|
10833
|
-
* TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
|
|
10834
|
-
* TODO: [🧠][💺] Can be done this on type-level?
|
|
10835
|
-
*/
|
|
10836
|
-
|
|
10837
11059
|
/**
|
|
10838
11060
|
* Stringify the PipelineJson with proper formatting
|
|
10839
11061
|
*
|
|
@@ -11183,46 +11405,6 @@
|
|
|
11183
11405
|
* Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
|
|
11184
11406
|
*/
|
|
11185
11407
|
|
|
11186
|
-
/**
|
|
11187
|
-
* @@@
|
|
11188
|
-
*
|
|
11189
|
-
* @public exported from `@promptbook/node`
|
|
11190
|
-
*/
|
|
11191
|
-
var wizzard = {
|
|
11192
|
-
/**
|
|
11193
|
-
* @@@!!!!!!
|
|
11194
|
-
*/
|
|
11195
|
-
run: function (book, inputParameters, onProgress) {
|
|
11196
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
11197
|
-
var tools, collection, pipeline, pipelineExecutor, result;
|
|
11198
|
-
return __generator(this, function (_a) {
|
|
11199
|
-
switch (_a.label) {
|
|
11200
|
-
case 0: return [4 /*yield*/, $provideExecutionToolsForNode()];
|
|
11201
|
-
case 1:
|
|
11202
|
-
tools = _a.sent();
|
|
11203
|
-
return [4 /*yield*/, createCollectionFromDirectory('./books', tools)];
|
|
11204
|
-
case 2:
|
|
11205
|
-
collection = _a.sent();
|
|
11206
|
-
return [4 /*yield*/, collection.getPipelineByUrl(book)];
|
|
11207
|
-
case 3:
|
|
11208
|
-
pipeline = _a.sent();
|
|
11209
|
-
pipelineExecutor = createPipelineExecutor({ pipeline: pipeline, tools: tools });
|
|
11210
|
-
return [4 /*yield*/, pipelineExecutor(inputParameters, onProgress)];
|
|
11211
|
-
case 4:
|
|
11212
|
-
result = _a.sent();
|
|
11213
|
-
// ▶ Fail if the execution was not successful
|
|
11214
|
-
assertsExecutionSuccessful(result);
|
|
11215
|
-
// ▶ Return the result
|
|
11216
|
-
return [2 /*return*/, result];
|
|
11217
|
-
}
|
|
11218
|
-
});
|
|
11219
|
-
});
|
|
11220
|
-
},
|
|
11221
|
-
};
|
|
11222
|
-
/**
|
|
11223
|
-
* TODO: !!!!!! Add to readmes - one markdown here imported in all packages
|
|
11224
|
-
*/
|
|
11225
|
-
|
|
11226
11408
|
exports.$execCommand = $execCommand;
|
|
11227
11409
|
exports.$execCommands = $execCommands;
|
|
11228
11410
|
exports.$provideExecutablesForNode = $provideExecutablesForNode;
|
|
@@ -11235,7 +11417,6 @@
|
|
|
11235
11417
|
exports.FileCacheStorage = FileCacheStorage;
|
|
11236
11418
|
exports.PROMPTBOOK_ENGINE_VERSION = PROMPTBOOK_ENGINE_VERSION;
|
|
11237
11419
|
exports.createCollectionFromDirectory = createCollectionFromDirectory;
|
|
11238
|
-
exports.wizzard = wizzard;
|
|
11239
11420
|
|
|
11240
11421
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
11241
11422
|
|