@promptbook/cli 0.92.0-3 → 0.92.0-30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/index.es.js +1589 -460
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/_packages/browser.index.d.ts +2 -0
- package/esm/typings/src/_packages/core.index.d.ts +22 -6
- package/esm/typings/src/_packages/deepseek.index.d.ts +2 -0
- package/esm/typings/src/_packages/google.index.d.ts +2 -0
- package/esm/typings/src/_packages/types.index.d.ts +4 -2
- package/esm/typings/src/_packages/utils.index.d.ts +2 -0
- package/esm/typings/src/cli/common/$provideLlmToolsForCli.d.ts +1 -1
- package/esm/typings/src/collection/PipelineCollection.d.ts +0 -2
- package/esm/typings/src/collection/SimplePipelineCollection.d.ts +1 -1
- package/esm/typings/src/commands/FOREACH/ForeachJson.d.ts +6 -6
- package/esm/typings/src/commands/FOREACH/foreachCommandParser.d.ts +0 -2
- package/esm/typings/src/commands/FORMFACTOR/formfactorCommandParser.d.ts +1 -1
- package/esm/typings/src/commands/_BOILERPLATE/boilerplateCommandParser.d.ts +1 -1
- package/esm/typings/src/commands/_common/types/CommandParser.d.ts +36 -28
- package/esm/typings/src/config.d.ts +41 -11
- package/esm/typings/src/constants.d.ts +43 -2
- package/esm/typings/src/conversion/archive/loadArchive.d.ts +2 -2
- package/esm/typings/src/errors/0-BoilerplateError.d.ts +2 -2
- package/esm/typings/src/executables/$provideExecutablesForNode.d.ts +1 -1
- package/esm/typings/src/executables/apps/locateLibreoffice.d.ts +2 -1
- package/esm/typings/src/executables/apps/locatePandoc.d.ts +2 -1
- package/esm/typings/src/executables/platforms/locateAppOnLinux.d.ts +2 -1
- package/esm/typings/src/executables/platforms/locateAppOnMacOs.d.ts +2 -1
- package/esm/typings/src/executables/platforms/locateAppOnWindows.d.ts +2 -1
- package/esm/typings/src/execution/AbstractTaskResult.d.ts +1 -1
- package/esm/typings/src/execution/CommonToolsOptions.d.ts +5 -1
- package/esm/typings/src/execution/LlmExecutionToolsConstructor.d.ts +2 -1
- package/esm/typings/src/execution/PipelineExecutorResult.d.ts +4 -2
- package/esm/typings/src/execution/createPipelineExecutor/$OngoingTaskResult.d.ts +12 -9
- package/esm/typings/src/execution/createPipelineExecutor/10-executePipeline.d.ts +12 -9
- package/esm/typings/src/execution/createPipelineExecutor/20-executeTask.d.ts +11 -8
- package/esm/typings/src/execution/createPipelineExecutor/30-executeFormatSubvalues.d.ts +15 -3
- package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempts.d.ts +20 -14
- package/esm/typings/src/execution/createPipelineExecutor/computeCosineSimilarity.d.ts +13 -0
- package/esm/typings/src/execution/createPipelineExecutor/filterJustOutputParameters.d.ts +7 -6
- package/esm/typings/src/execution/createPipelineExecutor/getContextForTask.d.ts +5 -1
- package/esm/typings/src/execution/createPipelineExecutor/getExamplesForTask.d.ts +1 -1
- package/esm/typings/src/execution/createPipelineExecutor/getKnowledgeForTask.d.ts +21 -5
- package/esm/typings/src/execution/createPipelineExecutor/getReservedParametersForTask.d.ts +19 -5
- package/esm/typings/src/execution/createPipelineExecutor/knowledgePiecesToString.d.ts +9 -0
- package/esm/typings/src/execution/translation/automatic-translate/automatic-translators/LindatAutomaticTranslator.d.ts +4 -4
- package/esm/typings/src/execution/utils/checkExpectations.d.ts +1 -1
- package/esm/typings/src/execution/utils/uncertainNumber.d.ts +3 -2
- package/esm/typings/src/formats/_common/{FormatDefinition.d.ts → FormatParser.d.ts} +8 -6
- package/esm/typings/src/formats/_common/FormatSubvalueParser.d.ts +66 -0
- package/esm/typings/src/formats/csv/CsvFormatParser.d.ts +17 -0
- package/esm/typings/src/formats/csv/CsvSettings.d.ts +2 -2
- package/esm/typings/src/formats/csv/utils/csvParse.d.ts +12 -0
- package/esm/typings/src/formats/csv/utils/isValidCsvString.d.ts +1 -1
- package/esm/typings/src/formats/index.d.ts +2 -2
- package/esm/typings/src/formats/json/{JsonFormatDefinition.d.ts → JsonFormatParser.d.ts} +6 -6
- package/esm/typings/src/formats/json/utils/isValidJsonString.d.ts +1 -1
- package/esm/typings/src/formats/json/utils/jsonParse.d.ts +8 -0
- package/esm/typings/src/formats/text/{TextFormatDefinition.d.ts → TextFormatParser.d.ts} +7 -7
- package/esm/typings/src/formats/xml/XmlFormatParser.d.ts +19 -0
- package/esm/typings/src/formats/xml/utils/isValidXmlString.d.ts +1 -1
- package/esm/typings/src/formfactors/_boilerplate/BoilerplateFormfactorDefinition.d.ts +3 -2
- package/esm/typings/src/formfactors/_common/AbstractFormfactorDefinition.d.ts +16 -7
- package/esm/typings/src/formfactors/_common/FormfactorDefinition.d.ts +3 -1
- package/esm/typings/src/formfactors/_common/string_formfactor_name.d.ts +2 -1
- package/esm/typings/src/formfactors/chatbot/ChatbotFormfactorDefinition.d.ts +2 -2
- package/esm/typings/src/formfactors/completion/CompletionFormfactorDefinition.d.ts +29 -0
- package/esm/typings/src/formfactors/generator/GeneratorFormfactorDefinition.d.ts +2 -1
- package/esm/typings/src/formfactors/generic/GenericFormfactorDefinition.d.ts +2 -2
- package/esm/typings/src/formfactors/index.d.ts +33 -8
- package/esm/typings/src/formfactors/matcher/MatcherFormfactorDefinition.d.ts +4 -2
- package/esm/typings/src/formfactors/sheets/SheetsFormfactorDefinition.d.ts +3 -2
- package/esm/typings/src/formfactors/translator/TranslatorFormfactorDefinition.d.ts +3 -2
- package/esm/typings/src/high-level-abstractions/index.d.ts +2 -2
- package/esm/typings/src/llm-providers/_common/register/$llmToolsMetadataRegister.d.ts +3 -3
- package/esm/typings/src/llm-providers/_common/register/$llmToolsRegister.d.ts +3 -3
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsConfigurationFromEnv.d.ts +4 -4
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForTestingAndScriptsAndPlayground.d.ts +4 -3
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsFromEnv.d.ts +17 -4
- package/esm/typings/src/llm-providers/_common/register/LlmToolsConfiguration.d.ts +11 -4
- package/esm/typings/src/llm-providers/_common/register/LlmToolsMetadata.d.ts +27 -5
- package/esm/typings/src/llm-providers/_common/register/LlmToolsOptions.d.ts +9 -2
- package/esm/typings/src/llm-providers/_common/register/createLlmToolsFromConfiguration.d.ts +12 -3
- package/esm/typings/src/llm-providers/_common/utils/cache/CacheItem.d.ts +10 -5
- package/esm/typings/src/llm-providers/_common/utils/cache/CacheLlmToolsOptions.d.ts +5 -3
- package/esm/typings/src/llm-providers/_common/utils/cache/cacheLlmTools.d.ts +3 -3
- package/esm/typings/src/llm-providers/_common/utils/count-total-usage/limitTotalUsage.d.ts +5 -5
- package/esm/typings/src/llm-providers/anthropic-claude/anthropic-claude-models.d.ts +1 -1
- package/esm/typings/src/llm-providers/azure-openai/AzureOpenAiExecutionTools.d.ts +4 -0
- package/esm/typings/src/llm-providers/deepseek/deepseek-models.d.ts +23 -0
- package/esm/typings/src/llm-providers/google/google-models.d.ts +23 -0
- package/esm/typings/src/llm-providers/openai/OpenAiExecutionTools.d.ts +4 -0
- package/esm/typings/src/llm-providers/openai/openai-models.d.ts +1 -1
- package/esm/typings/src/llm-providers/openai/register-configuration.d.ts +2 -2
- package/esm/typings/src/llm-providers/openai/register-constructor.d.ts +2 -2
- package/esm/typings/src/migrations/migratePipeline.d.ts +9 -0
- package/esm/typings/src/other/templates/getBookTemplates.d.ts +2 -2
- package/esm/typings/src/personas/preparePersona.d.ts +1 -1
- package/esm/typings/src/pipeline/PipelineInterface/PipelineInterface.d.ts +3 -3
- package/esm/typings/src/pipeline/PipelineInterface/constants.d.ts +1 -1
- package/esm/typings/src/pipeline/PipelineInterface/getPipelineInterface.d.ts +1 -1
- package/esm/typings/src/pipeline/PipelineInterface/isPipelineImplementingInterface.d.ts +5 -4
- package/esm/typings/src/pipeline/PipelineInterface/isPipelineInterfacesEqual.d.ts +1 -1
- package/esm/typings/src/pipeline/PipelineJson/CommonTaskJson.d.ts +9 -6
- package/esm/typings/src/pipeline/PipelineJson/PersonaJson.d.ts +4 -2
- package/esm/typings/src/pipeline/PipelineJson/PipelineJson.d.ts +3 -2
- package/esm/typings/src/pipeline/PipelineString.d.ts +3 -1
- package/esm/typings/src/pipeline/book-notation.d.ts +2 -2
- package/esm/typings/src/postprocessing/utils/extractJsonBlock.d.ts +1 -1
- package/esm/typings/src/prepare/prepareTasks.d.ts +7 -4
- package/esm/typings/src/remote-server/openapi-types.d.ts +348 -6
- package/esm/typings/src/remote-server/openapi.d.ts +398 -4
- package/esm/typings/src/remote-server/types/RemoteServerOptions.d.ts +2 -1
- package/esm/typings/src/scrapers/_boilerplate/BoilerplateScraper.d.ts +3 -3
- package/esm/typings/src/scrapers/_boilerplate/createBoilerplateScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/_boilerplate/register-metadata.d.ts +1 -1
- package/esm/typings/src/scrapers/_common/Converter.d.ts +3 -1
- package/esm/typings/src/scrapers/_common/Scraper.d.ts +4 -3
- package/esm/typings/src/scrapers/_common/ScraperIntermediateSource.d.ts +4 -2
- package/esm/typings/src/scrapers/_common/register/$provideFilesystemForNode.d.ts +2 -1
- package/esm/typings/src/scrapers/_common/register/$provideScrapersForBrowser.d.ts +6 -3
- package/esm/typings/src/scrapers/_common/register/$provideScrapersForNode.d.ts +3 -5
- package/esm/typings/src/scrapers/_common/register/$scrapersMetadataRegister.d.ts +3 -3
- package/esm/typings/src/scrapers/_common/register/$scrapersRegister.d.ts +3 -2
- package/esm/typings/src/scrapers/_common/register/ScraperAndConverterMetadata.d.ts +8 -5
- package/esm/typings/src/scrapers/_common/register/ScraperConstructor.d.ts +2 -1
- package/esm/typings/src/scrapers/_common/utils/getScraperIntermediateSource.d.ts +6 -5
- package/esm/typings/src/scrapers/_common/utils/makeKnowledgeSourceHandler.d.ts +3 -1
- package/esm/typings/src/scrapers/document/createDocumentScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/document-legacy/createLegacyDocumentScraper.d.ts +2 -1
- package/esm/typings/src/scrapers/markdown/createMarkdownScraper.d.ts +4 -1
- package/esm/typings/src/scrapers/markitdown/MarkitdownScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/pdf/createPdfScraper.d.ts +2 -1
- package/esm/typings/src/scrapers/website/createWebsiteScraper.d.ts +3 -4
- package/esm/typings/src/scripting/javascript/postprocessing-functions.d.ts +5 -1
- package/esm/typings/src/storage/file-cache-storage/FileCacheStorage.d.ts +12 -5
- package/esm/typings/src/storage/file-cache-storage/FileCacheStorageOptions.d.ts +4 -2
- package/esm/typings/src/storage/file-cache-storage/utils/nameToSubfolderPath.d.ts +2 -1
- package/esm/typings/src/storage/local-storage/getIndexedDbStorage.d.ts +10 -0
- package/esm/typings/src/storage/local-storage/utils/makePromptbookStorageFromIndexedDb.d.ts +7 -0
- package/esm/typings/src/storage/local-storage/utils/makePromptbookStorageFromWebStorage.d.ts +2 -1
- package/esm/typings/src/types/IntermediateFilesStrategy.d.ts +2 -1
- package/esm/typings/src/types/ModelVariant.d.ts +5 -5
- package/esm/typings/src/types/typeAliases.d.ts +17 -13
- package/esm/typings/src/utils/$Register.d.ts +8 -7
- package/esm/typings/src/utils/editable/edit-pipeline-string/addPipelineCommand.d.ts +2 -2
- package/esm/typings/src/utils/editable/edit-pipeline-string/deflatePipeline.d.ts +4 -1
- package/esm/typings/src/utils/editable/utils/isFlatPipeline.d.ts +2 -1
- package/esm/typings/src/utils/environment/$getGlobalScope.d.ts +2 -1
- package/esm/typings/src/utils/expectation-counters/index.d.ts +1 -1
- package/esm/typings/src/utils/markdown/extractAllListItemsFromMarkdown.d.ts +1 -1
- package/esm/typings/src/utils/normalization/nameToUriPart.d.ts +4 -4
- package/esm/typings/src/utils/normalization/nameToUriParts.d.ts +4 -4
- package/esm/typings/src/utils/normalization/normalize-to-kebab-case.d.ts +3 -3
- package/esm/typings/src/utils/normalization/normalizeTo_SCREAMING_CASE.d.ts +3 -3
- package/esm/typings/src/utils/normalization/normalizeTo_camelCase.d.ts +4 -4
- package/esm/typings/src/utils/normalization/normalizeTo_snake_case.d.ts +3 -3
- package/esm/typings/src/utils/normalization/removeDiacritics.d.ts +3 -3
- package/esm/typings/src/utils/normalization/searchKeywords.d.ts +4 -1
- package/esm/typings/src/utils/normalization/titleToName.d.ts +4 -4
- package/esm/typings/src/utils/organization/empty_object.d.ts +2 -2
- package/esm/typings/src/utils/organization/just_empty_object.d.ts +4 -4
- package/esm/typings/src/utils/parameters/mapAvailableToExpectedParameters.d.ts +7 -7
- package/esm/typings/src/utils/serialization/clonePipeline.d.ts +4 -3
- package/esm/typings/src/utils/serialization/deepClone.d.ts +5 -1
- package/esm/typings/src/utils/validators/javascriptName/isValidJavascriptName.d.ts +3 -3
- package/esm/typings/src/utils/validators/parameterName/validateParameterName.d.ts +5 -4
- package/esm/typings/src/version.d.ts +2 -1
- package/package.json +2 -1
- package/umd/index.umd.js +1597 -468
- package/umd/index.umd.js.map +1 -1
- package/esm/typings/src/formats/_common/FormatSubvalueDefinition.d.ts +0 -31
- package/esm/typings/src/formats/csv/CsvFormatDefinition.d.ts +0 -17
- package/esm/typings/src/formats/xml/XmlFormatDefinition.d.ts +0 -19
package/esm/index.es.js
CHANGED
|
@@ -21,12 +21,13 @@ import { lookup, extension } from 'mime-types';
|
|
|
21
21
|
import glob from 'glob-promise';
|
|
22
22
|
import moment from 'moment';
|
|
23
23
|
import express from 'express';
|
|
24
|
+
import * as OpenApiValidator from 'express-openapi-validator';
|
|
24
25
|
import http from 'http';
|
|
25
26
|
import { Server } from 'socket.io';
|
|
26
|
-
import * as OpenApiValidator from 'express-openapi-validator';
|
|
27
27
|
import swaggerUi from 'swagger-ui-express';
|
|
28
28
|
import Anthropic from '@anthropic-ai/sdk';
|
|
29
29
|
import { OpenAIClient, AzureKeyCredential } from '@azure/openai';
|
|
30
|
+
import Bottleneck from 'bottleneck';
|
|
30
31
|
import OpenAI from 'openai';
|
|
31
32
|
import { Readability } from '@mozilla/readability';
|
|
32
33
|
import { JSDOM } from 'jsdom';
|
|
@@ -46,7 +47,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
|
|
|
46
47
|
* @generated
|
|
47
48
|
* @see https://github.com/webgptorg/promptbook
|
|
48
49
|
*/
|
|
49
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.92.0-
|
|
50
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.92.0-30';
|
|
50
51
|
/**
|
|
51
52
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
52
53
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -162,6 +163,21 @@ const DEFAULT_BOOK_OUTPUT_PARAMETER_NAME = 'result';
|
|
|
162
163
|
* @public exported from `@promptbook/core`
|
|
163
164
|
*/
|
|
164
165
|
const DEFAULT_MAX_FILE_SIZE = 100 * 1024 * 1024; // 100MB
|
|
166
|
+
/**
|
|
167
|
+
* Threshold value that determines when a dataset is considered "big"
|
|
168
|
+
* and may require special handling or optimizations
|
|
169
|
+
*
|
|
170
|
+
* For example, when error occurs in one item of the big dataset, it will not fail the whole pipeline
|
|
171
|
+
*
|
|
172
|
+
* @public exported from `@promptbook/core`
|
|
173
|
+
*/
|
|
174
|
+
const BIG_DATASET_TRESHOLD = 50;
|
|
175
|
+
/**
|
|
176
|
+
* Placeholder text used to represent a placeholder value of failed operation
|
|
177
|
+
*
|
|
178
|
+
* @public exported from `@promptbook/core`
|
|
179
|
+
*/
|
|
180
|
+
const FAILED_VALUE_PLACEHOLDER = '!?';
|
|
165
181
|
/**
|
|
166
182
|
* Warning message for the generated sections and files files
|
|
167
183
|
*
|
|
@@ -246,6 +262,7 @@ const DEFAULT_MAX_PARALLEL_COUNT = 5; // <- TODO: [🤹♂️]
|
|
|
246
262
|
* @public exported from `@promptbook/core`
|
|
247
263
|
*/
|
|
248
264
|
const DEFAULT_MAX_EXECUTION_ATTEMPTS = 10; // <- TODO: [🤹♂️]
|
|
265
|
+
// <- TODO: [🐝]
|
|
249
266
|
/**
|
|
250
267
|
* Where to store your books
|
|
251
268
|
* This is kind of a "src" for your books
|
|
@@ -317,7 +334,7 @@ const MOMENT_ARG_THRESHOLDS = {
|
|
|
317
334
|
const DEFAULT_REMOTE_SERVER_URL = REMOTE_SERVER_URLS[0].urls[0];
|
|
318
335
|
// <- TODO: [🧜♂️]
|
|
319
336
|
/**
|
|
320
|
-
*
|
|
337
|
+
* Default settings for parsing and generating CSV files in Promptbook.
|
|
321
338
|
*
|
|
322
339
|
* @public exported from `@promptbook/core`
|
|
323
340
|
*/
|
|
@@ -328,13 +345,13 @@ const DEFAULT_CSV_SETTINGS = Object.freeze({
|
|
|
328
345
|
skipEmptyLines: true,
|
|
329
346
|
});
|
|
330
347
|
/**
|
|
331
|
-
*
|
|
348
|
+
* Controls whether verbose logging is enabled by default throughout the application.
|
|
332
349
|
*
|
|
333
350
|
* @public exported from `@promptbook/core`
|
|
334
351
|
*/
|
|
335
352
|
let DEFAULT_IS_VERBOSE = false;
|
|
336
353
|
/**
|
|
337
|
-
*
|
|
354
|
+
* Controls whether auto-installation of dependencies is enabled by default.
|
|
338
355
|
*
|
|
339
356
|
* @public exported from `@promptbook/core`
|
|
340
357
|
*/
|
|
@@ -346,7 +363,15 @@ const DEFAULT_IS_AUTO_INSTALLED = false;
|
|
|
346
363
|
*/
|
|
347
364
|
const DEFAULT_GET_PIPELINE_COLLECTION_FUNCTION_NAME = `getPipelineCollection`;
|
|
348
365
|
/**
|
|
349
|
-
*
|
|
366
|
+
* Default rate limits (requests per minute)
|
|
367
|
+
*
|
|
368
|
+
* Note: Adjust based on the provider tier you are have
|
|
369
|
+
*
|
|
370
|
+
* @public exported from `@promptbook/core`
|
|
371
|
+
*/
|
|
372
|
+
const DEFAULT_MAX_REQUESTS_PER_MINUTE = 60;
|
|
373
|
+
/**
|
|
374
|
+
* Indicates whether pipeline logic validation is enabled. When true, the pipeline logic is checked for consistency.
|
|
350
375
|
*
|
|
351
376
|
* @private within the repository
|
|
352
377
|
*/
|
|
@@ -686,7 +711,8 @@ class NotYetImplementedError extends Error {
|
|
|
686
711
|
}
|
|
687
712
|
|
|
688
713
|
/**
|
|
689
|
-
*
|
|
714
|
+
* Safely retrieves the global scope object (window in browser, global in Node.js)
|
|
715
|
+
* regardless of the JavaScript environment in which the code is running
|
|
690
716
|
*
|
|
691
717
|
* Note: `$` is used to indicate that this function is not a pure function - it access global scope
|
|
692
718
|
*
|
|
@@ -697,10 +723,10 @@ function $getGlobalScope() {
|
|
|
697
723
|
}
|
|
698
724
|
|
|
699
725
|
/**
|
|
700
|
-
*
|
|
726
|
+
* Normalizes a text string to SCREAMING_CASE (all uppercase with underscores).
|
|
701
727
|
*
|
|
702
|
-
* @param text
|
|
703
|
-
* @returns
|
|
728
|
+
* @param text The text string to be converted to SCREAMING_CASE format.
|
|
729
|
+
* @returns The normalized text in SCREAMING_CASE format.
|
|
704
730
|
* @example 'HELLO_WORLD'
|
|
705
731
|
* @example 'I_LOVE_PROMPTBOOK'
|
|
706
732
|
* @public exported from `@promptbook/utils`
|
|
@@ -752,10 +778,10 @@ function normalizeTo_SCREAMING_CASE(text) {
|
|
|
752
778
|
*/
|
|
753
779
|
|
|
754
780
|
/**
|
|
755
|
-
*
|
|
781
|
+
* Normalizes a text string to snake_case format.
|
|
756
782
|
*
|
|
757
|
-
* @param text
|
|
758
|
-
* @returns
|
|
783
|
+
* @param text The text string to be converted to snake_case format.
|
|
784
|
+
* @returns The normalized text in snake_case format.
|
|
759
785
|
* @example 'hello_world'
|
|
760
786
|
* @example 'i_love_promptbook'
|
|
761
787
|
* @public exported from `@promptbook/utils`
|
|
@@ -765,11 +791,11 @@ function normalizeTo_snake_case(text) {
|
|
|
765
791
|
}
|
|
766
792
|
|
|
767
793
|
/**
|
|
768
|
-
*
|
|
794
|
+
* Global registry for storing and managing registered entities of a given type.
|
|
769
795
|
*
|
|
770
796
|
* Note: `$` is used to indicate that this function is not a pure function - it accesses and adds variables in global scope.
|
|
771
797
|
*
|
|
772
|
-
* @private internal utility, exported are only
|
|
798
|
+
* @private internal utility, exported are only singleton instances of this class
|
|
773
799
|
*/
|
|
774
800
|
class $Register {
|
|
775
801
|
constructor(registerName) {
|
|
@@ -813,10 +839,10 @@ class $Register {
|
|
|
813
839
|
}
|
|
814
840
|
|
|
815
841
|
/**
|
|
816
|
-
*
|
|
842
|
+
* Register for LLM tools metadata.
|
|
817
843
|
*
|
|
818
844
|
* Note: `$` is used to indicate that this interacts with the global scope
|
|
819
|
-
* @singleton Only one instance of each register is created per build, but
|
|
845
|
+
* @singleton Only one instance of each register is created per build, but there can be more instances across different builds or environments.
|
|
820
846
|
* @public exported from `@promptbook/core`
|
|
821
847
|
*/
|
|
822
848
|
const $llmToolsMetadataRegister = new $Register('llm_tools_metadata');
|
|
@@ -825,10 +851,10 @@ const $llmToolsMetadataRegister = new $Register('llm_tools_metadata');
|
|
|
825
851
|
*/
|
|
826
852
|
|
|
827
853
|
/**
|
|
828
|
-
*
|
|
854
|
+
* Register for LLM tools.
|
|
829
855
|
*
|
|
830
856
|
* Note: `$` is used to indicate that this interacts with the global scope
|
|
831
|
-
* @singleton Only one instance of each register is created per build, but
|
|
857
|
+
* @singleton Only one instance of each register is created per build, but there can be more instances across different builds or environments.
|
|
832
858
|
* @public exported from `@promptbook/core`
|
|
833
859
|
*/
|
|
834
860
|
const $llmToolsRegister = new $Register('llm_execution_tools_constructors');
|
|
@@ -1004,6 +1030,42 @@ function $sideEffect(...sideEffectSubjects) {
|
|
|
1004
1030
|
keepUnused(...sideEffectSubjects);
|
|
1005
1031
|
}
|
|
1006
1032
|
|
|
1033
|
+
/**
|
|
1034
|
+
* Converts a JavaScript Object Notation (JSON) string into an object.
|
|
1035
|
+
*
|
|
1036
|
+
* Note: This is wrapper around `JSON.parse()` with better error and type handling
|
|
1037
|
+
*
|
|
1038
|
+
* @public exported from `@promptbook/utils`
|
|
1039
|
+
*/
|
|
1040
|
+
function jsonParse(value) {
|
|
1041
|
+
if (value === undefined) {
|
|
1042
|
+
throw new Error(`Can not parse JSON from undefined value.`);
|
|
1043
|
+
}
|
|
1044
|
+
else if (typeof value !== 'string') {
|
|
1045
|
+
console.error('Can not parse JSON from non-string value.', { text: value });
|
|
1046
|
+
throw new Error(spaceTrim(`
|
|
1047
|
+
Can not parse JSON from non-string value.
|
|
1048
|
+
|
|
1049
|
+
The value type: ${typeof value}
|
|
1050
|
+
See more in console.
|
|
1051
|
+
`));
|
|
1052
|
+
}
|
|
1053
|
+
try {
|
|
1054
|
+
return JSON.parse(value);
|
|
1055
|
+
}
|
|
1056
|
+
catch (error) {
|
|
1057
|
+
if (!(error instanceof Error)) {
|
|
1058
|
+
throw error;
|
|
1059
|
+
}
|
|
1060
|
+
throw new Error(spaceTrim((block) => `
|
|
1061
|
+
${block(error.message)}
|
|
1062
|
+
|
|
1063
|
+
The JSON text:
|
|
1064
|
+
${block(value)}
|
|
1065
|
+
`));
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1007
1069
|
/**
|
|
1008
1070
|
* Convert identification to Promptbook token
|
|
1009
1071
|
*
|
|
@@ -1052,7 +1114,8 @@ function TODO_USE(...value) {
|
|
|
1052
1114
|
}
|
|
1053
1115
|
|
|
1054
1116
|
/**
|
|
1055
|
-
*
|
|
1117
|
+
* Provides filesystem access (for example for Node.js-based scrapers)
|
|
1118
|
+
* Creates a standardized filesystem interface that scrapers can use for file operations.
|
|
1056
1119
|
*
|
|
1057
1120
|
* @public exported from `@promptbook/node`
|
|
1058
1121
|
*/
|
|
@@ -1427,8 +1490,12 @@ function checkSerializableAsJson(options) {
|
|
|
1427
1490
|
*/
|
|
1428
1491
|
|
|
1429
1492
|
/**
|
|
1430
|
-
*
|
|
1493
|
+
* Creates a deep clone of the given object
|
|
1431
1494
|
*
|
|
1495
|
+
* Note: This method only works for objects that are fully serializable to JSON and do not contain functions, Dates, or special types.
|
|
1496
|
+
*
|
|
1497
|
+
* @param objectValue The object to clone.
|
|
1498
|
+
* @returns A deep, writable clone of the input object.
|
|
1432
1499
|
* @public exported from `@promptbook/utils`
|
|
1433
1500
|
*/
|
|
1434
1501
|
function deepClone(objectValue) {
|
|
@@ -1483,6 +1550,26 @@ function exportJson(options) {
|
|
|
1483
1550
|
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
1484
1551
|
*/
|
|
1485
1552
|
|
|
1553
|
+
// <- TODO: Maybe do better levels of trust
|
|
1554
|
+
/**
|
|
1555
|
+
* How is the model provider important?
|
|
1556
|
+
*
|
|
1557
|
+
* @public exported from `@promptbook/core`
|
|
1558
|
+
*/
|
|
1559
|
+
const MODEL_ORDERS = {
|
|
1560
|
+
/**
|
|
1561
|
+
* Top-tier models, e.g. OpenAI, Anthropic,...
|
|
1562
|
+
*/
|
|
1563
|
+
TOP_TIER: 333,
|
|
1564
|
+
/**
|
|
1565
|
+
* Mid-tier models, e.g. Llama, Mistral, etc.
|
|
1566
|
+
*/
|
|
1567
|
+
NORMAL: 100,
|
|
1568
|
+
/**
|
|
1569
|
+
* Low-tier models, e.g. Phi, Tiny, etc.
|
|
1570
|
+
*/
|
|
1571
|
+
LOW_TIER: 0,
|
|
1572
|
+
};
|
|
1486
1573
|
/**
|
|
1487
1574
|
* Order of keys in the pipeline JSON
|
|
1488
1575
|
*
|
|
@@ -1510,13 +1597,19 @@ const ORDER_OF_PIPELINE_JSON = [
|
|
|
1510
1597
|
*/
|
|
1511
1598
|
const REPLACING_NONCE = 'ptbkauk42kV2dzao34faw7FudQUHYPtW';
|
|
1512
1599
|
/**
|
|
1513
|
-
*
|
|
1600
|
+
* Nonce which is used as string which is not occurring in normal text
|
|
1601
|
+
*
|
|
1602
|
+
* @private within the repository
|
|
1603
|
+
*/
|
|
1604
|
+
const SALT_NONCE = 'ptbkghhewbvruets21t54et5';
|
|
1605
|
+
/**
|
|
1606
|
+
* Placeholder value indicating a parameter is missing its value.
|
|
1514
1607
|
*
|
|
1515
1608
|
* @private within the repository
|
|
1516
1609
|
*/
|
|
1517
1610
|
const RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
|
|
1518
1611
|
/**
|
|
1519
|
-
*
|
|
1612
|
+
* Placeholder value indicating a parameter is restricted and cannot be used directly.
|
|
1520
1613
|
*
|
|
1521
1614
|
* @private within the repository
|
|
1522
1615
|
*/
|
|
@@ -1951,10 +2044,10 @@ for (let i = 0; i < defaultDiacriticsRemovalMap.length; i++) {
|
|
|
1951
2044
|
*/
|
|
1952
2045
|
|
|
1953
2046
|
/**
|
|
1954
|
-
*
|
|
2047
|
+
* Removes diacritic marks (accents) from characters in a string.
|
|
1955
2048
|
*
|
|
1956
|
-
* @param input
|
|
1957
|
-
* @returns
|
|
2049
|
+
* @param input The string containing diacritics to be normalized.
|
|
2050
|
+
* @returns The string with diacritics removed or normalized.
|
|
1958
2051
|
* @public exported from `@promptbook/utils`
|
|
1959
2052
|
*/
|
|
1960
2053
|
function removeDiacritics(input) {
|
|
@@ -1968,10 +2061,10 @@ function removeDiacritics(input) {
|
|
|
1968
2061
|
*/
|
|
1969
2062
|
|
|
1970
2063
|
/**
|
|
1971
|
-
*
|
|
2064
|
+
* Converts a given text to kebab-case format.
|
|
1972
2065
|
*
|
|
1973
|
-
* @param text
|
|
1974
|
-
* @returns
|
|
2066
|
+
* @param text The text to be converted.
|
|
2067
|
+
* @returns The kebab-case formatted string.
|
|
1975
2068
|
* @example 'hello-world'
|
|
1976
2069
|
* @example 'i-love-promptbook'
|
|
1977
2070
|
* @public exported from `@promptbook/utils`
|
|
@@ -2019,11 +2112,11 @@ function normalizeToKebabCase(text) {
|
|
|
2019
2112
|
*/
|
|
2020
2113
|
|
|
2021
2114
|
/**
|
|
2022
|
-
*
|
|
2115
|
+
* Converts a title string into a normalized name.
|
|
2023
2116
|
*
|
|
2024
|
-
* @param value
|
|
2025
|
-
* @returns
|
|
2026
|
-
* @example
|
|
2117
|
+
* @param value The title string to be converted to a name.
|
|
2118
|
+
* @returns A normalized name derived from the input title.
|
|
2119
|
+
* @example 'Hello World!' -> 'hello-world'
|
|
2027
2120
|
* @public exported from `@promptbook/utils`
|
|
2028
2121
|
*/
|
|
2029
2122
|
function titleToName(value) {
|
|
@@ -2043,7 +2136,8 @@ function titleToName(value) {
|
|
|
2043
2136
|
}
|
|
2044
2137
|
|
|
2045
2138
|
/**
|
|
2046
|
-
*
|
|
2139
|
+
* Converts a name to a properly formatted subfolder path for cache storage.
|
|
2140
|
+
* Handles normalization and path formatting to create consistent cache directory structures.
|
|
2047
2141
|
*
|
|
2048
2142
|
* @private for `FileCacheStorage`
|
|
2049
2143
|
*/
|
|
@@ -2052,7 +2146,10 @@ function nameToSubfolderPath(name) {
|
|
|
2052
2146
|
}
|
|
2053
2147
|
|
|
2054
2148
|
/**
|
|
2055
|
-
*
|
|
2149
|
+
* A storage implementation that caches data in files organized in a directory structure.
|
|
2150
|
+
* Provides methods for retrieving, storing, and managing cached data on the filesystem.
|
|
2151
|
+
*
|
|
2152
|
+
* This class implements the PromptbookStorage interface for filesystem-based caching.
|
|
2056
2153
|
*
|
|
2057
2154
|
* @public exported from `@promptbook/node`
|
|
2058
2155
|
*/
|
|
@@ -2065,7 +2162,8 @@ class FileCacheStorage {
|
|
|
2065
2162
|
}
|
|
2066
2163
|
}
|
|
2067
2164
|
/**
|
|
2068
|
-
*
|
|
2165
|
+
* Converts a storage key to a filesystem path where the data should be stored.
|
|
2166
|
+
* Creates a consistent, deterministic file path based on the key string.
|
|
2069
2167
|
*/
|
|
2070
2168
|
getFilenameForKey(key) {
|
|
2071
2169
|
// TODO: [👬] DRY
|
|
@@ -2077,7 +2175,8 @@ class FileCacheStorage {
|
|
|
2077
2175
|
...nameToSubfolderPath(hash /* <- TODO: [🎎] Maybe add some SHA256 prefix */), `${name.substring(0, MAX_FILENAME_LENGTH)}.json`);
|
|
2078
2176
|
}
|
|
2079
2177
|
/**
|
|
2080
|
-
*
|
|
2178
|
+
* Returns the current value associated with the given key, or null if the given key does not exist.
|
|
2179
|
+
* Retrieves the cached data from the file system storage.
|
|
2081
2180
|
*/
|
|
2082
2181
|
async getItem(key) {
|
|
2083
2182
|
const filename = this.getFilenameForKey(key);
|
|
@@ -2085,12 +2184,13 @@ class FileCacheStorage {
|
|
|
2085
2184
|
return null;
|
|
2086
2185
|
}
|
|
2087
2186
|
const fileContent = await readFile(filename, 'utf-8');
|
|
2088
|
-
const value =
|
|
2187
|
+
const value = jsonParse(fileContent);
|
|
2089
2188
|
// TODO: [🌗]
|
|
2090
2189
|
return value;
|
|
2091
2190
|
}
|
|
2092
2191
|
/**
|
|
2093
|
-
*
|
|
2192
|
+
* Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.
|
|
2193
|
+
* Persists data to the file system, creating necessary directory structure if it doesn't exist.
|
|
2094
2194
|
*/
|
|
2095
2195
|
async setItem(key, value) {
|
|
2096
2196
|
const filename = this.getFilenameForKey(key);
|
|
@@ -2102,7 +2202,8 @@ class FileCacheStorage {
|
|
|
2102
2202
|
await writeFile(filename, fileContent, 'utf-8');
|
|
2103
2203
|
}
|
|
2104
2204
|
/**
|
|
2105
|
-
*
|
|
2205
|
+
* Removes the key/value pair with the given key from the storage, if a key/value pair with the given key exists.
|
|
2206
|
+
* Deletes the corresponding file from the filesystem.
|
|
2106
2207
|
*/
|
|
2107
2208
|
async removeItem(key) {
|
|
2108
2209
|
const filename = this.getFilenameForKey(key);
|
|
@@ -2581,6 +2682,23 @@ class RemoteLlmExecutionTools {
|
|
|
2581
2682
|
* TODO: [🧠] Maybe remove `@promptbook/remote-client` and just use `@promptbook/core`
|
|
2582
2683
|
*/
|
|
2583
2684
|
|
|
2685
|
+
/**
|
|
2686
|
+
* Parses the task and returns the list of all parameter names
|
|
2687
|
+
*
|
|
2688
|
+
* @param template the string template with parameters in {curly} braces
|
|
2689
|
+
* @returns the list of parameter names
|
|
2690
|
+
* @public exported from `@promptbook/utils`
|
|
2691
|
+
*/
|
|
2692
|
+
function extractParameterNames(template) {
|
|
2693
|
+
const matches = template.matchAll(/{\w+}/g);
|
|
2694
|
+
const parameterNames = new Set();
|
|
2695
|
+
for (const match of matches) {
|
|
2696
|
+
const parameterName = match[0].slice(1, -1);
|
|
2697
|
+
parameterNames.add(parameterName);
|
|
2698
|
+
}
|
|
2699
|
+
return parameterNames;
|
|
2700
|
+
}
|
|
2701
|
+
|
|
2584
2702
|
/**
|
|
2585
2703
|
* Stores data in memory (HEAP)
|
|
2586
2704
|
*
|
|
@@ -2670,13 +2788,36 @@ function cacheLlmTools(llmTools, options = {}) {
|
|
|
2670
2788
|
const callCommonModel = async (prompt) => {
|
|
2671
2789
|
const { parameters, content, modelRequirements } = prompt;
|
|
2672
2790
|
// <- Note: These are relevant things from the prompt that the cache key should depend on.
|
|
2791
|
+
// TODO: Maybe some standalone function for normalization of content for cache
|
|
2792
|
+
let normalizedContent = content;
|
|
2793
|
+
normalizedContent = normalizedContent.replace(/\s+/g, ' ');
|
|
2794
|
+
normalizedContent = normalizedContent.split('\r\n').join('\n');
|
|
2795
|
+
normalizedContent = spaceTrim(normalizedContent);
|
|
2796
|
+
// Note: Do not need to save everything in the cache, just the relevant parameters
|
|
2797
|
+
const relevantParameterNames = extractParameterNames(content);
|
|
2798
|
+
const relevantParameters = Object.fromEntries(Object.entries(parameters).filter(([key]) => relevantParameterNames.has(key)));
|
|
2799
|
+
const keyHashBase = { relevantParameters, normalizedContent, modelRequirements };
|
|
2673
2800
|
const key = titleToName(prompt.title.substring(0, MAX_FILENAME_LENGTH - 10) +
|
|
2674
2801
|
'-' +
|
|
2675
|
-
sha256(hexEncoder.parse(JSON.stringify(
|
|
2802
|
+
sha256(hexEncoder.parse(JSON.stringify(keyHashBase)))
|
|
2803
|
+
.toString( /* hex */)
|
|
2804
|
+
.substring(0, 10 - 1));
|
|
2676
2805
|
const cacheItem = !isCacheReloaded ? await storage.getItem(key) : null;
|
|
2677
2806
|
if (cacheItem) {
|
|
2807
|
+
console.log('!!! Cache hit for key:', { key, keyHashBase });
|
|
2678
2808
|
return cacheItem.promptResult;
|
|
2679
2809
|
}
|
|
2810
|
+
console.log('!!! Cache miss for key:', key, {
|
|
2811
|
+
prompt,
|
|
2812
|
+
'prompt.title': prompt.title,
|
|
2813
|
+
MAX_FILENAME_LENGTH,
|
|
2814
|
+
keyHashBase,
|
|
2815
|
+
parameters,
|
|
2816
|
+
relevantParameters,
|
|
2817
|
+
content,
|
|
2818
|
+
normalizedContent,
|
|
2819
|
+
modelRequirements,
|
|
2820
|
+
});
|
|
2680
2821
|
let promptResult;
|
|
2681
2822
|
variant: switch (prompt.modelRequirements.modelVariant) {
|
|
2682
2823
|
case 'CHAT':
|
|
@@ -2697,7 +2838,16 @@ function cacheLlmTools(llmTools, options = {}) {
|
|
|
2697
2838
|
await storage.setItem(key, {
|
|
2698
2839
|
date: $getCurrentDate(),
|
|
2699
2840
|
promptbookVersion: PROMPTBOOK_ENGINE_VERSION,
|
|
2700
|
-
|
|
2841
|
+
bookVersion: BOOK_LANGUAGE_VERSION,
|
|
2842
|
+
prompt: {
|
|
2843
|
+
...prompt,
|
|
2844
|
+
parameters: Object.entries(parameters).length === Object.entries(relevantParameters).length
|
|
2845
|
+
? parameters
|
|
2846
|
+
: {
|
|
2847
|
+
...relevantParameters,
|
|
2848
|
+
note: `<- Note: Only relevant parameters are stored in the cache`,
|
|
2849
|
+
},
|
|
2850
|
+
},
|
|
2701
2851
|
promptResult,
|
|
2702
2852
|
});
|
|
2703
2853
|
return promptResult;
|
|
@@ -2723,9 +2873,9 @@ function cacheLlmTools(llmTools, options = {}) {
|
|
|
2723
2873
|
/**
|
|
2724
2874
|
* TODO: [🧠][💸] Maybe make some common abstraction `interceptLlmTools` and use here (or use javascript Proxy?)
|
|
2725
2875
|
* TODO: [🧠] Is there some meaningfull way how to test this util
|
|
2726
|
-
* TODO: [👷♂️]
|
|
2727
|
-
*
|
|
2728
|
-
*
|
|
2876
|
+
* TODO: [👷♂️] Comprehensive manual about construction of llmTools
|
|
2877
|
+
* Detailed explanation about caching strategies and appropriate storage selection for different use cases
|
|
2878
|
+
* Examples of how to combine multiple interceptors for advanced caching, logging, and usage tracking
|
|
2729
2879
|
*/
|
|
2730
2880
|
|
|
2731
2881
|
/**
|
|
@@ -2915,9 +3065,8 @@ function countUsage(llmTools) {
|
|
|
2915
3065
|
*/
|
|
2916
3066
|
|
|
2917
3067
|
/**
|
|
2918
|
-
*
|
|
3068
|
+
* Provides LLM tools configuration by reading environment variables.
|
|
2919
3069
|
*
|
|
2920
|
-
* @@@ .env
|
|
2921
3070
|
* Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access `.env` file
|
|
2922
3071
|
*
|
|
2923
3072
|
* It looks for environment variables:
|
|
@@ -2925,7 +3074,8 @@ function countUsage(llmTools) {
|
|
|
2925
3074
|
* - `process.env.ANTHROPIC_CLAUDE_API_KEY`
|
|
2926
3075
|
* - ...
|
|
2927
3076
|
*
|
|
2928
|
-
* @
|
|
3077
|
+
* @see Environment variables documentation or .env file for required variables.
|
|
3078
|
+
* @returns A promise that resolves to the LLM tools configuration, or null if configuration is incomplete or missing.
|
|
2929
3079
|
* @public exported from `@promptbook/node`
|
|
2930
3080
|
*/
|
|
2931
3081
|
async function $provideLlmToolsConfigurationFromEnv() {
|
|
@@ -3139,11 +3289,16 @@ function joinLlmExecutionTools(...llmExecutionTools) {
|
|
|
3139
3289
|
*/
|
|
3140
3290
|
|
|
3141
3291
|
/**
|
|
3142
|
-
*
|
|
3292
|
+
* Creates LLM execution tools from provided configuration objects
|
|
3293
|
+
*
|
|
3294
|
+
* Instantiates and configures LLM tool instances for each configuration entry,
|
|
3295
|
+
* combining them into a unified interface via MultipleLlmExecutionTools.
|
|
3143
3296
|
*
|
|
3144
3297
|
* Note: This function is not cached, every call creates new instance of `MultipleLlmExecutionTools`
|
|
3145
3298
|
*
|
|
3146
|
-
* @
|
|
3299
|
+
* @param configuration Array of LLM tool configurations to instantiate
|
|
3300
|
+
* @param options Additional options for configuring the LLM tools
|
|
3301
|
+
* @returns A unified interface combining all successfully instantiated LLM tools
|
|
3147
3302
|
* @public exported from `@promptbook/core`
|
|
3148
3303
|
*/
|
|
3149
3304
|
function createLlmToolsFromConfiguration(configuration, options = {}) {
|
|
@@ -3182,7 +3337,11 @@ function createLlmToolsFromConfiguration(configuration, options = {}) {
|
|
|
3182
3337
|
/**
|
|
3183
3338
|
* TODO: [🎌] Together with `createLlmToolsFromConfiguration` + 'EXECUTION_TOOLS_CLASSES' gets to `@promptbook/core` ALL model providers, make this more efficient
|
|
3184
3339
|
* TODO: [🧠][🎌] Dynamically install required providers
|
|
3185
|
-
* TODO:
|
|
3340
|
+
* TODO: We should implement an interactive configuration wizard that would:
|
|
3341
|
+
* 1. Detect which LLM providers are available in the environment
|
|
3342
|
+
* 2. Guide users through required configuration settings for each provider
|
|
3343
|
+
* 3. Allow testing connections before completing setup
|
|
3344
|
+
* 4. Generate appropriate configuration code for application integration
|
|
3186
3345
|
* TODO: [🧠][🍛] Which name is better `createLlmToolsFromConfig` or `createLlmToolsFromConfiguration`?
|
|
3187
3346
|
* TODO: [🧠] Is there some meaningfull way how to test this util
|
|
3188
3347
|
* TODO: This should be maybe not under `_common` but under `utils`
|
|
@@ -3190,11 +3349,14 @@ function createLlmToolsFromConfiguration(configuration, options = {}) {
|
|
|
3190
3349
|
*/
|
|
3191
3350
|
|
|
3192
3351
|
/**
|
|
3193
|
-
*
|
|
3352
|
+
* Automatically configures LLM tools from environment variables in Node.js
|
|
3353
|
+
*
|
|
3354
|
+
* This utility function detects available LLM providers based on environment variables
|
|
3355
|
+
* and creates properly configured LLM execution tools for each detected provider.
|
|
3194
3356
|
*
|
|
3195
3357
|
* Note: This function is not cached, every call creates new instance of `MultipleLlmExecutionTools`
|
|
3196
3358
|
*
|
|
3197
|
-
*
|
|
3359
|
+
* Supports environment variables from .env files when dotenv is configured
|
|
3198
3360
|
* Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access `.env` file
|
|
3199
3361
|
*
|
|
3200
3362
|
* It looks for environment variables:
|
|
@@ -3202,7 +3364,8 @@ function createLlmToolsFromConfiguration(configuration, options = {}) {
|
|
|
3202
3364
|
* - `process.env.ANTHROPIC_CLAUDE_API_KEY`
|
|
3203
3365
|
* - ...
|
|
3204
3366
|
*
|
|
3205
|
-
* @
|
|
3367
|
+
* @param options Configuration options for the LLM tools
|
|
3368
|
+
* @returns A unified interface containing all detected and configured LLM tools
|
|
3206
3369
|
* @public exported from `@promptbook/node`
|
|
3207
3370
|
*/
|
|
3208
3371
|
async function $provideLlmToolsFromEnv(options = {}) {
|
|
@@ -3228,7 +3391,16 @@ async function $provideLlmToolsFromEnv(options = {}) {
|
|
|
3228
3391
|
return createLlmToolsFromConfiguration(configuration, options);
|
|
3229
3392
|
}
|
|
3230
3393
|
/**
|
|
3231
|
-
* TODO:
|
|
3394
|
+
* TODO: The architecture for LLM tools configuration consists of three key functions:
|
|
3395
|
+
* 1. `$provideLlmToolsFromEnv` - High-level function that detects available providers from env vars and returns ready-to-use LLM tools
|
|
3396
|
+
* 2. `$provideLlmToolsConfigurationFromEnv` - Middle layer that extracts configuration objects from environment variables
|
|
3397
|
+
* 3. `createLlmToolsFromConfiguration` - Low-level function that instantiates LLM tools from explicit configuration
|
|
3398
|
+
*
|
|
3399
|
+
* This layered approach allows flexibility in how tools are configured:
|
|
3400
|
+
* - Use $provideLlmToolsFromEnv for automatic detection and setup in Node.js environments
|
|
3401
|
+
* - Use $provideLlmToolsConfigurationFromEnv to extract config objects for modification before instantiation
|
|
3402
|
+
* - Use createLlmToolsFromConfiguration for explicit control over tool configurations
|
|
3403
|
+
*
|
|
3232
3404
|
* TODO: [🧠][🍛] Which name is better `$provideLlmToolsFromEnv` or `$provideLlmToolsFromEnvironment`?
|
|
3233
3405
|
* TODO: [🧠] Is there some meaningfull way how to test this util
|
|
3234
3406
|
* Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
|
|
@@ -3420,7 +3592,7 @@ async function $provideLlmToolsForCli(options) {
|
|
|
3420
3592
|
password,
|
|
3421
3593
|
}),
|
|
3422
3594
|
});
|
|
3423
|
-
const { isSuccess, message, error, identification } = (await response.
|
|
3595
|
+
const { isSuccess, message, error, identification } = jsonParse(await response.text());
|
|
3424
3596
|
if (message) {
|
|
3425
3597
|
if (isSuccess) {
|
|
3426
3598
|
console.log(colors.green(message));
|
|
@@ -3641,7 +3813,8 @@ function $execCommand(options) {
|
|
|
3641
3813
|
*/
|
|
3642
3814
|
|
|
3643
3815
|
/**
|
|
3644
|
-
*
|
|
3816
|
+
* Attempts to locate the specified application on a Linux system using the 'which' command.
|
|
3817
|
+
* Returns the path to the executable if found, or null otherwise.
|
|
3645
3818
|
*
|
|
3646
3819
|
* @private within the repository
|
|
3647
3820
|
*/
|
|
@@ -3684,7 +3857,8 @@ async function isExecutable(path, fs) {
|
|
|
3684
3857
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
3685
3858
|
const userhome = require('userhome');
|
|
3686
3859
|
/**
|
|
3687
|
-
*
|
|
3860
|
+
* Attempts to locate the specified application on a macOS system by checking standard application paths and using mdfind.
|
|
3861
|
+
* Returns the path to the executable if found, or null otherwise.
|
|
3688
3862
|
*
|
|
3689
3863
|
* @private within the repository
|
|
3690
3864
|
*/
|
|
@@ -3716,7 +3890,8 @@ async function locateAppOnMacOs({ macOsName, }) {
|
|
|
3716
3890
|
*/
|
|
3717
3891
|
|
|
3718
3892
|
/**
|
|
3719
|
-
*
|
|
3893
|
+
* Attempts to locate the specified application on a Windows system by searching common installation directories.
|
|
3894
|
+
* Returns the path to the executable if found, or null otherwise.
|
|
3720
3895
|
*
|
|
3721
3896
|
* @private within the repository
|
|
3722
3897
|
*/
|
|
@@ -3787,7 +3962,8 @@ function locateApp(options) {
|
|
|
3787
3962
|
*/
|
|
3788
3963
|
|
|
3789
3964
|
/**
|
|
3790
|
-
*
|
|
3965
|
+
* Locates the LibreOffice executable on the current system by searching platform-specific paths.
|
|
3966
|
+
* Returns the path to the executable if found, or null otherwise.
|
|
3791
3967
|
*
|
|
3792
3968
|
* @private within the repository
|
|
3793
3969
|
*/
|
|
@@ -3805,7 +3981,8 @@ function locateLibreoffice() {
|
|
|
3805
3981
|
*/
|
|
3806
3982
|
|
|
3807
3983
|
/**
|
|
3808
|
-
*
|
|
3984
|
+
* Locates the Pandoc executable on the current system by searching platform-specific paths.
|
|
3985
|
+
* Returns the path to the executable if found, or null otherwise.
|
|
3809
3986
|
*
|
|
3810
3987
|
* @private within the repository
|
|
3811
3988
|
*/
|
|
@@ -3823,7 +4000,7 @@ function locatePandoc() {
|
|
|
3823
4000
|
*/
|
|
3824
4001
|
|
|
3825
4002
|
/**
|
|
3826
|
-
*
|
|
4003
|
+
* Provides paths to required executables (i.e. as Pandoc and LibreOffice) for Node.js environments.
|
|
3827
4004
|
*
|
|
3828
4005
|
* @public exported from `@promptbook/node`
|
|
3829
4006
|
*/
|
|
@@ -3843,10 +4020,11 @@ async function $provideExecutablesForNode(options) {
|
|
|
3843
4020
|
*/
|
|
3844
4021
|
|
|
3845
4022
|
/**
|
|
3846
|
-
*
|
|
4023
|
+
* Registry for all available scrapers in the system.
|
|
4024
|
+
* Central point for registering and accessing different types of content scrapers.
|
|
3847
4025
|
*
|
|
3848
4026
|
* Note: `$` is used to indicate that this interacts with the global scope
|
|
3849
|
-
* @singleton Only one instance of each register is created per build, but
|
|
4027
|
+
* @singleton Only one instance of each register is created per build, but there can be more than one in different build modules
|
|
3850
4028
|
* @public exported from `@promptbook/core`
|
|
3851
4029
|
*/
|
|
3852
4030
|
const $scrapersRegister = new $Register('scraper_constructors');
|
|
@@ -3855,11 +4033,9 @@ const $scrapersRegister = new $Register('scraper_constructors');
|
|
|
3855
4033
|
*/
|
|
3856
4034
|
|
|
3857
4035
|
/**
|
|
3858
|
-
*
|
|
3859
|
-
*
|
|
3860
|
-
*
|
|
3861
|
-
* 2) @@@
|
|
3862
|
-
*
|
|
4036
|
+
* Provides a collection of scrapers optimized for Node.js environment.
|
|
4037
|
+
* 1) `provideScrapersForNode` use as default
|
|
4038
|
+
* 2) `provideScrapersForBrowser` use in limited browser environment *
|
|
3863
4039
|
* @public exported from `@promptbook/node`
|
|
3864
4040
|
*/
|
|
3865
4041
|
async function $provideScrapersForNode(tools, options) {
|
|
@@ -3884,10 +4060,10 @@ async function $provideScrapersForNode(tools, options) {
|
|
|
3884
4060
|
*/
|
|
3885
4061
|
|
|
3886
4062
|
/**
|
|
3887
|
-
*
|
|
4063
|
+
* Global registry for storing metadata about all available scrapers and converters.
|
|
3888
4064
|
*
|
|
3889
|
-
* Note: `$` is used to indicate that this interacts with the global scope
|
|
3890
|
-
* @singleton Only one instance of each register is created per build, but
|
|
4065
|
+
* Note: `$` is used to indicate that this interacts with the global scope.
|
|
4066
|
+
* @singleton Only one instance of each register is created per build, but there can be more in different contexts (e.g., tests).
|
|
3891
4067
|
* @public exported from `@promptbook/core`
|
|
3892
4068
|
*/
|
|
3893
4069
|
const $scrapersMetadataRegister = new $Register('scrapers_metadata');
|
|
@@ -4451,7 +4627,7 @@ async function loadArchive(filePath, fs) {
|
|
|
4451
4627
|
if (!indexFile) {
|
|
4452
4628
|
throw new UnexpectedError(`Archive does not contain 'index.book.json' file`);
|
|
4453
4629
|
}
|
|
4454
|
-
const collectionJson =
|
|
4630
|
+
const collectionJson = jsonParse(await indexFile.async('text'));
|
|
4455
4631
|
for (const pipeline of collectionJson) {
|
|
4456
4632
|
validatePipeline(pipeline);
|
|
4457
4633
|
}
|
|
@@ -4461,13 +4637,13 @@ async function loadArchive(filePath, fs) {
|
|
|
4461
4637
|
* Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
|
|
4462
4638
|
*/
|
|
4463
4639
|
|
|
4464
|
-
var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book",formfactorName:"GENERIC",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",resultingParameterName:"knowledgePieces",dependentParameterNames:["knowledgeContent"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Knowledge from Markdown\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book`\n- INPUT PARAMETER `{knowledgeContent}` Markdown document content\n- OUTPUT PARAMETER `{knowledgePieces}` The knowledge JSON object\n\n## Knowledge\n\n<!-- TODO: [🍆] -FORMAT JSON -->\n\n```markdown\nYou are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}\n```\n\n`-> {knowledgePieces}`\n"}],sourceFile:"./books/prepare-knowledge-from-markdown.book"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.book",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",resultingParameterName:"keywords",dependentParameterNames:["knowledgePieceContent"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Keywords\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-keywords.book`\n- INPUT PARAMETER `{knowledgePieceContent}` The content\n- OUTPUT PARAMETER `{keywords}` Keywords separated by comma\n\n## Knowledge\n\n<!-- TODO: [🍆] -FORMAT JSON -->\n\n```markdown\nYou are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}\n```\n\n`-> {keywords}`\n"}],sourceFile:"./books/prepare-knowledge-keywords.book"},{title:"Prepare Knowledge-piece Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.book",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"knowledge",title:"Knowledge",content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Knowledge-piece Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-title.book`\n- INPUT PARAMETER `{knowledgePieceContent}` The content\n- OUTPUT PARAMETER `{title}` The title of the document\n\n## Knowledge\n\n- EXPECT MIN 1 WORD\n- EXPECT MAX 8 WORDS\n\n```markdown\nYou are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-knowledge-title.book"},{title:"Prepare Persona",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.book",formfactorName:"GENERIC",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"make-model-requirements",title:"Make modelRequirements",content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Example\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n- Your output format is JSON object\n- Write just the JSON object, no other text should be present\n- It contains the following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",resultingParameterName:"modelRequirements",format:"JSON",dependentParameterNames:["availableModelNames","personaDescription"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Persona\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-persona.book`\n- INPUT PARAMETER `{availableModelNames}` List of available model names separated by comma (,)\n- INPUT PARAMETER `{personaDescription}` Description of the persona\n- OUTPUT PARAMETER `{modelRequirements}` Specific requirements for the model\n\n## Make modelRequirements\n\n- FORMAT JSON\n\n```markdown\nYou are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Example\n\n\\`\\`\\`json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n\\`\\`\\`\n\n## Instructions\n\n- Your output format is JSON object\n- Write just the JSON object, no other text should be present\n- It contains the following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}\n```\n\n`-> {modelRequirements}`\n"}],sourceFile:"./books/prepare-persona.book"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-title.book",formfactorName:"GENERIC",parameters:[{name:"book",description:"The book to prepare the title for",isInput:true,isOutput:false},{name:"title",description:"Best title for the book",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"make-title",title:"Make title",content:"Make best title for given text which describes the workflow:\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\n- Title starts with emoticon\n- Title should not mention the input and output of the workflow but the main purpose of the workflow\n _For example, not \"✍ Convert Knowledge-piece to title\" but \"✍ Title\"_\n\n## The workflow\n\n> {book}",resultingParameterName:"title",expectations:{words:{min:1,max:8},lines:{min:1,max:1}},dependentParameterNames:["book"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-title.book`\n- INPUT PARAMETER `{book}` The book to prepare the title for\n- OUTPUT PARAMETER `{title}` Best title for the book\n\n## Make title\n\n- EXPECT MIN 1 Word\n- EXPECT MAX 8 Words\n- EXPECT EXACTLY 1 Line\n\n```markdown\nMake best title for given text which describes the workflow:\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\n- Title starts with emoticon\n- Title should not mention the input and output of the workflow but the main purpose of the workflow\n _For example, not \"✍ Convert Knowledge-piece to title\" but \"✍ Title\"_\n\n## The workflow\n\n> {book}\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-title.book"}];
|
|
4640
|
+
var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book",formfactorName:"GENERIC",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",resultingParameterName:"knowledgePieces",dependentParameterNames:["knowledgeContent"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Knowledge from Markdown\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book`\n- INPUT PARAMETER `{knowledgeContent}` Markdown document content\n- OUTPUT PARAMETER `{knowledgePieces}` The knowledge JSON object\n\n## Knowledge\n\n<!-- TODO: [🍆] -FORMAT JSON -->\n\n```markdown\nYou are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}\n```\n\n`-> {knowledgePieces}`\n"}],sourceFile:"./books/prepare-knowledge-from-markdown.book"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.book",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",resultingParameterName:"keywords",dependentParameterNames:["knowledgePieceContent"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Keywords\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-keywords.book`\n- INPUT PARAMETER `{knowledgePieceContent}` The content\n- OUTPUT PARAMETER `{keywords}` Keywords separated by comma\n\n## Knowledge\n\n<!-- TODO: [🍆] -FORMAT JSON -->\n\n```markdown\nYou are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}\n```\n\n`-> {keywords}`\n"}],sourceFile:"./books/prepare-knowledge-keywords.book"},{title:"Prepare Knowledge-piece Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.book",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"knowledge",title:"Knowledge",content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Knowledge-piece Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-title.book`\n- INPUT PARAMETER `{knowledgePieceContent}` The content\n- OUTPUT PARAMETER `{title}` The title of the document\n\n## Knowledge\n\n- EXPECT MIN 1 WORD\n- EXPECT MAX 8 WORDS\n\n```markdown\nYou are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-knowledge-title.book"},{title:"Prepare Persona",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.book",formfactorName:"GENERIC",parameters:[{name:"availableModels",description:"List of available model names together with their descriptions as JSON",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelsRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"make-model-requirements",title:"Make modelRequirements",content:"You are an experienced AI engineer, you need to find the best models for virtual assistants:\n\n## Example\n\n```json\n[\n {\n \"modelName\": \"gpt-4o\",\n \"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n \"temperature\": 0.7\n },\n {\n \"modelName\": \"claude-3-5-sonnet\",\n \"systemMessage\": \"You are a friendly and knowledgeable chatbot.\",\n \"temperature\": 0.5\n }\n]\n```\n\n## Instructions\n\n- Your output format is JSON array\n- Sort best-fitting models first\n- Omit any models that are not suitable\n- Write just the JSON, no other text should be present\n- Array contain items with following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nHere are the available models:\n\n```json\n{availableModels}\n```\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",resultingParameterName:"modelsRequirements",format:"JSON",dependentParameterNames:["availableModels","personaDescription"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Persona\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-persona.book`\n- INPUT PARAMETER `{availableModels}` List of available model names together with their descriptions as JSON\n- INPUT PARAMETER `{personaDescription}` Description of the persona\n- OUTPUT PARAMETER `{modelsRequirements}` Specific requirements for the model\n\n## Make modelRequirements\n\n- FORMAT JSON\n\n```markdown\nYou are an experienced AI engineer, you need to find the best models for virtual assistants:\n\n## Example\n\n\\`\\`\\`json\n[\n {\n \"modelName\": \"gpt-4o\",\n \"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n \"temperature\": 0.7\n },\n {\n \"modelName\": \"claude-3-5-sonnet\",\n \"systemMessage\": \"You are a friendly and knowledgeable chatbot.\",\n \"temperature\": 0.5\n }\n]\n\\`\\`\\`\n\n## Instructions\n\n- Your output format is JSON array\n- Sort best-fitting models first\n- Omit any models that are not suitable\n- Write just the JSON, no other text should be present\n- Array contain items with following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nHere are the available models:\n\n\\`\\`\\`json\n{availableModels}\n\\`\\`\\`\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}\n```\n\n`-> {modelsRequirements}`\n"}],sourceFile:"./books/prepare-persona.book"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-title.book",formfactorName:"GENERIC",parameters:[{name:"book",description:"The book to prepare the title for",isInput:true,isOutput:false},{name:"title",description:"Best title for the book",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"make-title",title:"Make title",content:"Make best title for given text which describes the workflow:\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\n- Title starts with emoticon\n- Title should not mention the input and output of the workflow but the main purpose of the workflow\n _For example, not \"✍ Convert Knowledge-piece to title\" but \"✍ Title\"_\n\n## The workflow\n\n> {book}",resultingParameterName:"title",expectations:{words:{min:1,max:8},lines:{min:1,max:1}},dependentParameterNames:["book"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-title.book`\n- INPUT PARAMETER `{book}` The book to prepare the title for\n- OUTPUT PARAMETER `{title}` Best title for the book\n\n## Make title\n\n- EXPECT MIN 1 Word\n- EXPECT MAX 8 Words\n- EXPECT EXACTLY 1 Line\n\n```markdown\nMake best title for given text which describes the workflow:\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\n- Title starts with emoticon\n- Title should not mention the input and output of the workflow but the main purpose of the workflow\n _For example, not \"✍ Convert Knowledge-piece to title\" but \"✍ Title\"_\n\n## The workflow\n\n> {book}\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-title.book"}];
|
|
4465
4641
|
|
|
4466
4642
|
/**
|
|
4467
4643
|
* Function isValidJsonString will tell you if the string is valid JSON or not
|
|
4468
4644
|
*
|
|
4469
4645
|
* @param value The string to check
|
|
4470
|
-
* @returns
|
|
4646
|
+
* @returns `true` if the string is a valid JSON string, false otherwise
|
|
4471
4647
|
*
|
|
4472
4648
|
* @public exported from `@promptbook/utils`
|
|
4473
4649
|
*/
|
|
@@ -4697,23 +4873,6 @@ function taskParameterJsonToString(taskParameterJson) {
|
|
|
4697
4873
|
* TODO: [🧠] Should be in generated .book.md file GENERATOR_WARNING
|
|
4698
4874
|
*/
|
|
4699
4875
|
|
|
4700
|
-
/**
|
|
4701
|
-
* Parses the task and returns the list of all parameter names
|
|
4702
|
-
*
|
|
4703
|
-
* @param template the string template with parameters in {curly} braces
|
|
4704
|
-
* @returns the list of parameter names
|
|
4705
|
-
* @public exported from `@promptbook/utils`
|
|
4706
|
-
*/
|
|
4707
|
-
function extractParameterNames(template) {
|
|
4708
|
-
const matches = template.matchAll(/{\w+}/g);
|
|
4709
|
-
const parameterNames = new Set();
|
|
4710
|
-
for (const match of matches) {
|
|
4711
|
-
const parameterName = match[0].slice(1, -1);
|
|
4712
|
-
parameterNames.add(parameterName);
|
|
4713
|
-
}
|
|
4714
|
-
return parameterNames;
|
|
4715
|
-
}
|
|
4716
|
-
|
|
4717
4876
|
/**
|
|
4718
4877
|
* Unprepare just strips the preparation data of the pipeline
|
|
4719
4878
|
*
|
|
@@ -4722,7 +4881,7 @@ function extractParameterNames(template) {
|
|
|
4722
4881
|
*/
|
|
4723
4882
|
function unpreparePipeline(pipeline) {
|
|
4724
4883
|
let { personas, knowledgeSources, tasks } = pipeline;
|
|
4725
|
-
personas = personas.map((persona) => ({ ...persona,
|
|
4884
|
+
personas = personas.map((persona) => ({ ...persona, modelsRequirements: undefined, preparationIds: undefined }));
|
|
4726
4885
|
knowledgeSources = knowledgeSources.map((knowledgeSource) => ({ ...knowledgeSource, preparationIds: undefined }));
|
|
4727
4886
|
tasks = tasks.map((task) => {
|
|
4728
4887
|
let { dependentParameterNames } = task;
|
|
@@ -4763,7 +4922,7 @@ class SimplePipelineCollection {
|
|
|
4763
4922
|
/**
|
|
4764
4923
|
* Constructs a pipeline collection from pipelines
|
|
4765
4924
|
*
|
|
4766
|
-
* @param pipelines
|
|
4925
|
+
* @param pipelines Array of pipeline JSON objects to include in the collection
|
|
4767
4926
|
*
|
|
4768
4927
|
* Note: During the construction logic of all pipelines are validated
|
|
4769
4928
|
* Note: It is not recommended to use this constructor directly, use `createCollectionFromJson` *(or other variant)* instead
|
|
@@ -4875,15 +5034,21 @@ function createCollectionFromJson(...promptbooks) {
|
|
|
4875
5034
|
* @public exported from `@promptbook/core`
|
|
4876
5035
|
*/
|
|
4877
5036
|
function isPipelinePrepared(pipeline) {
|
|
4878
|
-
// Note: Ignoring `pipeline.preparations`
|
|
4879
|
-
// Note: Ignoring `pipeline.knowledgePieces`
|
|
5037
|
+
// Note: Ignoring `pipeline.preparations`
|
|
5038
|
+
// Note: Ignoring `pipeline.knowledgePieces`
|
|
4880
5039
|
if (pipeline.title === undefined || pipeline.title === '' || pipeline.title === DEFAULT_BOOK_TITLE) {
|
|
5040
|
+
// TODO: !!! Comment this out
|
|
5041
|
+
console.log('Pipeline is not prepared because title is undefined or empty', pipeline);
|
|
4881
5042
|
return false;
|
|
4882
5043
|
}
|
|
4883
|
-
if (!pipeline.personas.every((persona) => persona.
|
|
5044
|
+
if (!pipeline.personas.every((persona) => persona.modelsRequirements !== undefined)) {
|
|
5045
|
+
// TODO: !!! Comment this out
|
|
5046
|
+
console.log('Pipeline is not prepared because personas are not prepared', pipeline.personas);
|
|
4884
5047
|
return false;
|
|
4885
5048
|
}
|
|
4886
5049
|
if (!pipeline.knowledgeSources.every((knowledgeSource) => knowledgeSource.preparationIds !== undefined)) {
|
|
5050
|
+
// TODO: !!! Comment this out
|
|
5051
|
+
console.log('Pipeline is not prepared because knowledge sources are not prepared', pipeline.knowledgeSources);
|
|
4887
5052
|
return false;
|
|
4888
5053
|
}
|
|
4889
5054
|
/*
|
|
@@ -4904,6 +5069,35 @@ function isPipelinePrepared(pipeline) {
|
|
|
4904
5069
|
* - [♨] Are tasks prepared
|
|
4905
5070
|
*/
|
|
4906
5071
|
|
|
5072
|
+
/**
|
|
5073
|
+
* Serializes an error into a [🚉] JSON-serializable object
|
|
5074
|
+
*
|
|
5075
|
+
* @public exported from `@promptbook/utils`
|
|
5076
|
+
*/
|
|
5077
|
+
function serializeError(error) {
|
|
5078
|
+
const { name, message, stack } = error;
|
|
5079
|
+
const { id } = error;
|
|
5080
|
+
if (!Object.keys(ALL_ERRORS).includes(name)) {
|
|
5081
|
+
console.error(spaceTrim((block) => `
|
|
5082
|
+
|
|
5083
|
+
Cannot serialize error with name "${name}"
|
|
5084
|
+
|
|
5085
|
+
Authors of Promptbook probably forgot to add this error into the list of errors:
|
|
5086
|
+
https://github.com/webgptorg/promptbook/blob/main/src/errors/0-index.ts
|
|
5087
|
+
|
|
5088
|
+
|
|
5089
|
+
${block(stack || message)}
|
|
5090
|
+
|
|
5091
|
+
`));
|
|
5092
|
+
}
|
|
5093
|
+
return {
|
|
5094
|
+
name: name,
|
|
5095
|
+
message,
|
|
5096
|
+
stack,
|
|
5097
|
+
id, // Include id in the serialized object
|
|
5098
|
+
};
|
|
5099
|
+
}
|
|
5100
|
+
|
|
4907
5101
|
/**
|
|
4908
5102
|
* Recursively converts JSON strings to JSON objects
|
|
4909
5103
|
|
|
@@ -4922,7 +5116,7 @@ function jsonStringsToJsons(object) {
|
|
|
4922
5116
|
const newObject = { ...object };
|
|
4923
5117
|
for (const [key, value] of Object.entries(object)) {
|
|
4924
5118
|
if (typeof value === 'string' && isValidJsonString(value)) {
|
|
4925
|
-
newObject[key] =
|
|
5119
|
+
newObject[key] = jsonParse(value);
|
|
4926
5120
|
}
|
|
4927
5121
|
else {
|
|
4928
5122
|
newObject[key] = jsonStringsToJsons(value);
|
|
@@ -5073,35 +5267,6 @@ function createTask(options) {
|
|
|
5073
5267
|
* TODO: [🐚] Split into more files and make `PrepareTask` & `RemoteTask` + split the function
|
|
5074
5268
|
*/
|
|
5075
5269
|
|
|
5076
|
-
/**
|
|
5077
|
-
* Serializes an error into a [🚉] JSON-serializable object
|
|
5078
|
-
*
|
|
5079
|
-
* @public exported from `@promptbook/utils`
|
|
5080
|
-
*/
|
|
5081
|
-
function serializeError(error) {
|
|
5082
|
-
const { name, message, stack } = error;
|
|
5083
|
-
const { id } = error;
|
|
5084
|
-
if (!Object.keys(ALL_ERRORS).includes(name)) {
|
|
5085
|
-
console.error(spaceTrim((block) => `
|
|
5086
|
-
|
|
5087
|
-
Cannot serialize error with name "${name}"
|
|
5088
|
-
|
|
5089
|
-
Authors of Promptbook probably forgot to add this error into the list of errors:
|
|
5090
|
-
https://github.com/webgptorg/promptbook/blob/main/src/errors/0-index.ts
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
${block(stack || message)}
|
|
5094
|
-
|
|
5095
|
-
`));
|
|
5096
|
-
}
|
|
5097
|
-
return {
|
|
5098
|
-
name: name,
|
|
5099
|
-
message,
|
|
5100
|
-
stack,
|
|
5101
|
-
id, // Include id in the serialized object
|
|
5102
|
-
};
|
|
5103
|
-
}
|
|
5104
|
-
|
|
5105
5270
|
/**
|
|
5106
5271
|
* Format either small or big number
|
|
5107
5272
|
*
|
|
@@ -5344,7 +5509,7 @@ function union(...sets) {
|
|
|
5344
5509
|
}
|
|
5345
5510
|
|
|
5346
5511
|
/**
|
|
5347
|
-
*
|
|
5512
|
+
* Contains configuration options for parsing and generating CSV files, such as delimiters and quoting rules.
|
|
5348
5513
|
*
|
|
5349
5514
|
* @public exported from `@promptbook/core`
|
|
5350
5515
|
*/
|
|
@@ -5353,11 +5518,29 @@ const MANDATORY_CSV_SETTINGS = Object.freeze({
|
|
|
5353
5518
|
// encoding: 'utf-8',
|
|
5354
5519
|
});
|
|
5355
5520
|
|
|
5521
|
+
/**
|
|
5522
|
+
* Converts a CSV string into an object
|
|
5523
|
+
*
|
|
5524
|
+
* Note: This is wrapper around `papaparse.parse()` with better autohealing
|
|
5525
|
+
*
|
|
5526
|
+
* @private - for now until `@promptbook/csv` is released
|
|
5527
|
+
*/
|
|
5528
|
+
function csvParse(value /* <- TODO: string_csv */, settings, schema /* <- TODO: Make CSV Schemas */) {
|
|
5529
|
+
settings = { ...settings, ...MANDATORY_CSV_SETTINGS };
|
|
5530
|
+
// Note: Autoheal invalid '\n' characters
|
|
5531
|
+
if (settings.newline && !settings.newline.includes('\r') && value.includes('\r')) {
|
|
5532
|
+
console.warn('CSV string contains carriage return characters, but in the CSV settings the `newline` setting does not include them. Autohealing the CSV string.');
|
|
5533
|
+
value = value.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
5534
|
+
}
|
|
5535
|
+
const csv = parse(value, settings);
|
|
5536
|
+
return csv;
|
|
5537
|
+
}
|
|
5538
|
+
|
|
5356
5539
|
/**
|
|
5357
5540
|
* Function to check if a string is valid CSV
|
|
5358
5541
|
*
|
|
5359
5542
|
* @param value The string to check
|
|
5360
|
-
* @returns
|
|
5543
|
+
* @returns `true` if the string is a valid CSV string, false otherwise
|
|
5361
5544
|
*
|
|
5362
5545
|
* @public exported from `@promptbook/utils`
|
|
5363
5546
|
*/
|
|
@@ -5381,7 +5564,7 @@ function isValidCsvString(value) {
|
|
|
5381
5564
|
* @public exported from `@promptbook/core`
|
|
5382
5565
|
* <- TODO: [🏢] Export from package `@promptbook/csv`
|
|
5383
5566
|
*/
|
|
5384
|
-
const
|
|
5567
|
+
const CsvFormatParser = {
|
|
5385
5568
|
formatName: 'CSV',
|
|
5386
5569
|
aliases: ['SPREADSHEET', 'TABLE'],
|
|
5387
5570
|
isValid(value, settings, schema) {
|
|
@@ -5393,12 +5576,12 @@ const CsvFormatDefinition = {
|
|
|
5393
5576
|
heal(value, settings, schema) {
|
|
5394
5577
|
throw new Error('Not implemented');
|
|
5395
5578
|
},
|
|
5396
|
-
|
|
5579
|
+
subvalueParsers: [
|
|
5397
5580
|
{
|
|
5398
5581
|
subvalueName: 'ROW',
|
|
5399
|
-
async mapValues(
|
|
5400
|
-
|
|
5401
|
-
const csv =
|
|
5582
|
+
async mapValues(options) {
|
|
5583
|
+
const { value, outputParameterName, settings, mapCallback, onProgress } = options;
|
|
5584
|
+
const csv = csvParse(value, settings);
|
|
5402
5585
|
if (csv.errors.length !== 0) {
|
|
5403
5586
|
throw new CsvFormatError(spaceTrim((block) => `
|
|
5404
5587
|
CSV parsing error
|
|
@@ -5413,23 +5596,37 @@ const CsvFormatDefinition = {
|
|
|
5413
5596
|
${block(value)}
|
|
5414
5597
|
`));
|
|
5415
5598
|
}
|
|
5416
|
-
const mappedData =
|
|
5599
|
+
const mappedData = [];
|
|
5600
|
+
const length = csv.data.length;
|
|
5601
|
+
for (let index = 0; index < length; index++) {
|
|
5602
|
+
const row = csv.data[index];
|
|
5417
5603
|
if (row[outputParameterName]) {
|
|
5418
5604
|
throw new CsvFormatError(`Can not overwrite existing column "${outputParameterName}" in CSV row`);
|
|
5419
5605
|
}
|
|
5420
|
-
|
|
5606
|
+
const mappedRow = {
|
|
5421
5607
|
...row,
|
|
5422
|
-
[outputParameterName]: await mapCallback(row, index),
|
|
5608
|
+
[outputParameterName]: await mapCallback(row, index, length),
|
|
5423
5609
|
};
|
|
5424
|
-
|
|
5610
|
+
mappedData.push(mappedRow);
|
|
5611
|
+
if (onProgress) {
|
|
5612
|
+
// Note: Report the CSV with all rows mapped so far
|
|
5613
|
+
/*
|
|
5614
|
+
// TODO: [🛕] Report progress with all the rows including the pending ones
|
|
5615
|
+
const progressData = mappedData.map((row, i) =>
|
|
5616
|
+
i > index ? { ...row, [outputParameterName]: PENDING_VALUE_PLACEHOLDER } : row,
|
|
5617
|
+
);
|
|
5618
|
+
*/
|
|
5619
|
+
await onProgress(unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS }));
|
|
5620
|
+
}
|
|
5621
|
+
}
|
|
5425
5622
|
return unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
|
|
5426
5623
|
},
|
|
5427
5624
|
},
|
|
5428
5625
|
{
|
|
5429
5626
|
subvalueName: 'CELL',
|
|
5430
|
-
async mapValues(
|
|
5431
|
-
|
|
5432
|
-
const csv =
|
|
5627
|
+
async mapValues(options) {
|
|
5628
|
+
const { value, settings, mapCallback, onProgress } = options;
|
|
5629
|
+
const csv = csvParse(value, settings);
|
|
5433
5630
|
if (csv.errors.length !== 0) {
|
|
5434
5631
|
throw new CsvFormatError(spaceTrim((block) => `
|
|
5435
5632
|
CSV parsing error
|
|
@@ -5445,9 +5642,9 @@ const CsvFormatDefinition = {
|
|
|
5445
5642
|
`));
|
|
5446
5643
|
}
|
|
5447
5644
|
const mappedData = await Promise.all(csv.data.map(async (row, rowIndex) => {
|
|
5448
|
-
return /* not await */ Promise.all(Object.entries(row).map(async ([key, value], columnIndex) => {
|
|
5645
|
+
return /* not await */ Promise.all(Object.entries(row).map(async ([key, value], columnIndex, array) => {
|
|
5449
5646
|
const index = rowIndex * Object.keys(row).length + columnIndex;
|
|
5450
|
-
return /* not await */ mapCallback({ [key]: value }, index);
|
|
5647
|
+
return /* not await */ mapCallback({ [key]: value }, index, array.length);
|
|
5451
5648
|
}));
|
|
5452
5649
|
}));
|
|
5453
5650
|
return unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
|
|
@@ -5456,10 +5653,10 @@ const CsvFormatDefinition = {
|
|
|
5456
5653
|
],
|
|
5457
5654
|
};
|
|
5458
5655
|
/**
|
|
5459
|
-
* TODO: [🍓] In `
|
|
5460
|
-
* TODO: [🍓] In `
|
|
5461
|
-
* TODO: [🍓] In `
|
|
5462
|
-
* TODO: [🍓] In `
|
|
5656
|
+
* TODO: [🍓] In `CsvFormatParser` implement simple `isValid`
|
|
5657
|
+
* TODO: [🍓] In `CsvFormatParser` implement partial `canBeValid`
|
|
5658
|
+
* TODO: [🍓] In `CsvFormatParser` implement `heal
|
|
5659
|
+
* TODO: [🍓] In `CsvFormatParser` implement `subvalueParsers`
|
|
5463
5660
|
* TODO: [🏢] Allow to expect something inside CSV objects and other formats
|
|
5464
5661
|
*/
|
|
5465
5662
|
|
|
@@ -5468,7 +5665,7 @@ const CsvFormatDefinition = {
|
|
|
5468
5665
|
*
|
|
5469
5666
|
* @private still in development [🏢]
|
|
5470
5667
|
*/
|
|
5471
|
-
const
|
|
5668
|
+
const JsonFormatParser = {
|
|
5472
5669
|
formatName: 'JSON',
|
|
5473
5670
|
mimeType: 'application/json',
|
|
5474
5671
|
isValid(value, settings, schema) {
|
|
@@ -5480,28 +5677,28 @@ const JsonFormatDefinition = {
|
|
|
5480
5677
|
heal(value, settings, schema) {
|
|
5481
5678
|
throw new Error('Not implemented');
|
|
5482
5679
|
},
|
|
5483
|
-
|
|
5680
|
+
subvalueParsers: [],
|
|
5484
5681
|
};
|
|
5485
5682
|
/**
|
|
5486
5683
|
* TODO: [🧠] Maybe propper instance of object
|
|
5487
5684
|
* TODO: [0] Make string_serialized_json
|
|
5488
5685
|
* TODO: [1] Make type for JSON Settings and Schema
|
|
5489
5686
|
* TODO: [🧠] What to use for validating JSONs - JSON Schema, ZoD, typescript types/interfaces,...?
|
|
5490
|
-
* TODO: [🍓] In `
|
|
5491
|
-
* TODO: [🍓] In `
|
|
5492
|
-
* TODO: [🍓] In `
|
|
5493
|
-
* TODO: [🍓] In `
|
|
5687
|
+
* TODO: [🍓] In `JsonFormatParser` implement simple `isValid`
|
|
5688
|
+
* TODO: [🍓] In `JsonFormatParser` implement partial `canBeValid`
|
|
5689
|
+
* TODO: [🍓] In `JsonFormatParser` implement `heal
|
|
5690
|
+
* TODO: [🍓] In `JsonFormatParser` implement `subvalueParsers`
|
|
5494
5691
|
* TODO: [🏢] Allow to expect something inside JSON objects and other formats
|
|
5495
5692
|
*/
|
|
5496
5693
|
|
|
5497
5694
|
/**
|
|
5498
5695
|
* Definition for any text - this will be always valid
|
|
5499
5696
|
*
|
|
5500
|
-
* Note: This is not useful for validation, but for splitting and mapping with `
|
|
5697
|
+
* Note: This is not useful for validation, but for splitting and mapping with `subvalueParsers`
|
|
5501
5698
|
*
|
|
5502
5699
|
* @public exported from `@promptbook/core`
|
|
5503
5700
|
*/
|
|
5504
|
-
const
|
|
5701
|
+
const TextFormatParser = {
|
|
5505
5702
|
formatName: 'TEXT',
|
|
5506
5703
|
isValid(value) {
|
|
5507
5704
|
return typeof value === 'string';
|
|
@@ -5510,19 +5707,20 @@ const TextFormatDefinition = {
|
|
|
5510
5707
|
return typeof partialValue === 'string';
|
|
5511
5708
|
},
|
|
5512
5709
|
heal() {
|
|
5513
|
-
throw new UnexpectedError('It does not make sense to call `
|
|
5710
|
+
throw new UnexpectedError('It does not make sense to call `TextFormatParser.heal`');
|
|
5514
5711
|
},
|
|
5515
|
-
|
|
5712
|
+
subvalueParsers: [
|
|
5516
5713
|
{
|
|
5517
5714
|
subvalueName: 'LINE',
|
|
5518
|
-
async mapValues(
|
|
5715
|
+
async mapValues(options) {
|
|
5716
|
+
const { value, mapCallback, onProgress } = options;
|
|
5519
5717
|
const lines = value.split('\n');
|
|
5520
|
-
const mappedLines = await Promise.all(lines.map((lineContent, lineNumber) =>
|
|
5718
|
+
const mappedLines = await Promise.all(lines.map((lineContent, lineNumber, array) =>
|
|
5521
5719
|
// TODO: [🧠] Maybe option to skip empty line
|
|
5522
5720
|
/* not await */ mapCallback({
|
|
5523
5721
|
lineContent,
|
|
5524
5722
|
// TODO: [🧠] Maybe also put here `lineNumber`
|
|
5525
|
-
}, lineNumber)));
|
|
5723
|
+
}, lineNumber, array.length)));
|
|
5526
5724
|
return mappedLines.join('\n');
|
|
5527
5725
|
},
|
|
5528
5726
|
},
|
|
@@ -5532,10 +5730,10 @@ const TextFormatDefinition = {
|
|
|
5532
5730
|
/**
|
|
5533
5731
|
* TODO: [1] Make type for XML Text and Schema
|
|
5534
5732
|
* TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages available as subvalues
|
|
5535
|
-
* TODO: [🍓] In `
|
|
5536
|
-
* TODO: [🍓] In `
|
|
5537
|
-
* TODO: [🍓] In `
|
|
5538
|
-
* TODO: [🍓] In `
|
|
5733
|
+
* TODO: [🍓] In `TextFormatParser` implement simple `isValid`
|
|
5734
|
+
* TODO: [🍓] In `TextFormatParser` implement partial `canBeValid`
|
|
5735
|
+
* TODO: [🍓] In `TextFormatParser` implement `heal
|
|
5736
|
+
* TODO: [🍓] In `TextFormatParser` implement `subvalueParsers`
|
|
5539
5737
|
* TODO: [🏢] Allow to expect something inside each item of list and other formats
|
|
5540
5738
|
*/
|
|
5541
5739
|
|
|
@@ -5543,7 +5741,7 @@ const TextFormatDefinition = {
|
|
|
5543
5741
|
* Function to check if a string is valid XML
|
|
5544
5742
|
*
|
|
5545
5743
|
* @param value
|
|
5546
|
-
* @returns
|
|
5744
|
+
* @returns `true` if the string is a valid XML string, false otherwise
|
|
5547
5745
|
*
|
|
5548
5746
|
* @public exported from `@promptbook/utils`
|
|
5549
5747
|
*/
|
|
@@ -5568,7 +5766,7 @@ function isValidXmlString(value) {
|
|
|
5568
5766
|
*
|
|
5569
5767
|
* @private still in development [🏢]
|
|
5570
5768
|
*/
|
|
5571
|
-
const
|
|
5769
|
+
const XmlFormatParser = {
|
|
5572
5770
|
formatName: 'XML',
|
|
5573
5771
|
mimeType: 'application/xml',
|
|
5574
5772
|
isValid(value, settings, schema) {
|
|
@@ -5580,17 +5778,17 @@ const XmlFormatDefinition = {
|
|
|
5580
5778
|
heal(value, settings, schema) {
|
|
5581
5779
|
throw new Error('Not implemented');
|
|
5582
5780
|
},
|
|
5583
|
-
|
|
5781
|
+
subvalueParsers: [],
|
|
5584
5782
|
};
|
|
5585
5783
|
/**
|
|
5586
5784
|
* TODO: [🧠] Maybe propper instance of object
|
|
5587
5785
|
* TODO: [0] Make string_serialized_xml
|
|
5588
5786
|
* TODO: [1] Make type for XML Settings and Schema
|
|
5589
5787
|
* TODO: [🧠] What to use for validating XMLs - XSD,...
|
|
5590
|
-
* TODO: [🍓] In `
|
|
5591
|
-
* TODO: [🍓] In `
|
|
5592
|
-
* TODO: [🍓] In `
|
|
5593
|
-
* TODO: [🍓] In `
|
|
5788
|
+
* TODO: [🍓] In `XmlFormatParser` implement simple `isValid`
|
|
5789
|
+
* TODO: [🍓] In `XmlFormatParser` implement partial `canBeValid`
|
|
5790
|
+
* TODO: [🍓] In `XmlFormatParser` implement `heal
|
|
5791
|
+
* TODO: [🍓] In `XmlFormatParser` implement `subvalueParsers`
|
|
5594
5792
|
* TODO: [🏢] Allow to expect something inside XML and other formats
|
|
5595
5793
|
*/
|
|
5596
5794
|
|
|
@@ -5599,24 +5797,19 @@ const XmlFormatDefinition = {
|
|
|
5599
5797
|
*
|
|
5600
5798
|
* @private internal index of `...` <- TODO [🏢]
|
|
5601
5799
|
*/
|
|
5602
|
-
const FORMAT_DEFINITIONS = [
|
|
5603
|
-
JsonFormatDefinition,
|
|
5604
|
-
XmlFormatDefinition,
|
|
5605
|
-
TextFormatDefinition,
|
|
5606
|
-
CsvFormatDefinition,
|
|
5607
|
-
];
|
|
5800
|
+
const FORMAT_DEFINITIONS = [JsonFormatParser, XmlFormatParser, TextFormatParser, CsvFormatParser];
|
|
5608
5801
|
/**
|
|
5609
5802
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
5610
5803
|
*/
|
|
5611
5804
|
|
|
5612
5805
|
/**
|
|
5613
|
-
* Maps available parameters to expected parameters
|
|
5806
|
+
* Maps available parameters to expected parameters for a pipeline task.
|
|
5614
5807
|
*
|
|
5615
5808
|
* The strategy is:
|
|
5616
|
-
* 1)
|
|
5617
|
-
* 2)
|
|
5809
|
+
* 1) First, match parameters by name where both available and expected.
|
|
5810
|
+
* 2) Then, if there are unmatched expected and available parameters, map them by order.
|
|
5618
5811
|
*
|
|
5619
|
-
* @throws {PipelineExecutionError}
|
|
5812
|
+
* @throws {PipelineExecutionError} If the number of unmatched expected and available parameters does not match, or mapping is ambiguous.
|
|
5620
5813
|
* @private within the repository used in `createPipelineExecutor`
|
|
5621
5814
|
*/
|
|
5622
5815
|
function mapAvailableToExpectedParameters(options) {
|
|
@@ -5639,7 +5832,7 @@ function mapAvailableToExpectedParameters(options) {
|
|
|
5639
5832
|
else if (!availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) ;
|
|
5640
5833
|
}
|
|
5641
5834
|
if (expectedParameterNames.size === 0) {
|
|
5642
|
-
// Note: [👨👨👧] Now we can freeze `mappedParameters` to prevent
|
|
5835
|
+
// Note: [👨👨👧] Now we can freeze `mappedParameters` to prevent accidental modifications after mapping
|
|
5643
5836
|
Object.freeze(mappedParameters);
|
|
5644
5837
|
return mappedParameters;
|
|
5645
5838
|
}
|
|
@@ -5670,7 +5863,7 @@ function mapAvailableToExpectedParameters(options) {
|
|
|
5670
5863
|
for (let i = 0; i < expectedParameterNames.size; i++) {
|
|
5671
5864
|
mappedParameters[expectedParameterNamesArray[i]] = availableParameters[availableParametersNamesArray[i]];
|
|
5672
5865
|
}
|
|
5673
|
-
// Note: [👨👨👧] Now we can freeze `mappedParameters` to prevent
|
|
5866
|
+
// Note: [👨👨👧] Now we can freeze `mappedParameters` to prevent accidental modifications after mapping
|
|
5674
5867
|
Object.freeze(mappedParameters);
|
|
5675
5868
|
return mappedParameters;
|
|
5676
5869
|
}
|
|
@@ -5774,7 +5967,7 @@ function extractJsonBlock(markdown) {
|
|
|
5774
5967
|
}
|
|
5775
5968
|
/**
|
|
5776
5969
|
* TODO: Add some auto-healing logic + extract YAML, JSON5, TOML, etc.
|
|
5777
|
-
* TODO: [🏢] Make this logic part of `
|
|
5970
|
+
* TODO: [🏢] Make this logic part of `JsonFormatParser` or `isValidJsonString`
|
|
5778
5971
|
*/
|
|
5779
5972
|
|
|
5780
5973
|
/**
|
|
@@ -5836,10 +6029,12 @@ function templateParameters(template, parameters) {
|
|
|
5836
6029
|
throw new PipelineExecutionError('Parameter is already opened or not closed');
|
|
5837
6030
|
}
|
|
5838
6031
|
if (parameters[parameterName] === undefined) {
|
|
6032
|
+
console.log('!!! templateParameters 1', { parameterName, template, parameters });
|
|
5839
6033
|
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
5840
6034
|
}
|
|
5841
6035
|
let parameterValue = parameters[parameterName];
|
|
5842
6036
|
if (parameterValue === undefined) {
|
|
6037
|
+
console.log('!!! templateParameters 2', { parameterName, template, parameters });
|
|
5843
6038
|
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
5844
6039
|
}
|
|
5845
6040
|
parameterValue = valueToString(parameterValue);
|
|
@@ -5995,7 +6190,7 @@ const CountUtils = {
|
|
|
5995
6190
|
PAGES: countPages,
|
|
5996
6191
|
};
|
|
5997
6192
|
/**
|
|
5998
|
-
* TODO: [🧠][🤠] This should be probbably as part of `
|
|
6193
|
+
* TODO: [🧠][🤠] This should be probbably as part of `TextFormatParser`
|
|
5999
6194
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
6000
6195
|
*/
|
|
6001
6196
|
|
|
@@ -6023,13 +6218,17 @@ function checkExpectations(expectations, value) {
|
|
|
6023
6218
|
}
|
|
6024
6219
|
/**
|
|
6025
6220
|
* TODO: [💝] Unite object for expecting amount and format
|
|
6026
|
-
* TODO: [🧠][🤠] This should be part of `
|
|
6221
|
+
* TODO: [🧠][🤠] This should be part of `TextFormatParser`
|
|
6027
6222
|
* Note: [💝] and [🤠] are interconnected together
|
|
6028
6223
|
*/
|
|
6029
6224
|
|
|
6030
6225
|
/**
|
|
6031
|
-
*
|
|
6226
|
+
* Executes a pipeline task with multiple attempts, including joker and retry logic. Handles different task types
|
|
6227
|
+
* (prompt, script, dialog, etc.), applies postprocessing, checks expectations, and updates the execution report.
|
|
6228
|
+
* Throws errors if execution fails after all attempts.
|
|
6032
6229
|
*
|
|
6230
|
+
* @param options - The options for execution, including task, parameters, pipeline, and configuration.
|
|
6231
|
+
* @returns The result string of the executed task.
|
|
6033
6232
|
* @private internal utility of `createPipelineExecutor`
|
|
6034
6233
|
*/
|
|
6035
6234
|
async function executeAttempts(options) {
|
|
@@ -6251,7 +6450,7 @@ async function executeAttempts(options) {
|
|
|
6251
6450
|
if (task.format) {
|
|
6252
6451
|
if (task.format === 'JSON') {
|
|
6253
6452
|
if (!isValidJsonString($ongoingTaskResult.$resultString || '')) {
|
|
6254
|
-
// TODO: [🏢] Do more universally via `
|
|
6453
|
+
// TODO: [🏢] Do more universally via `FormatParser`
|
|
6255
6454
|
try {
|
|
6256
6455
|
$ongoingTaskResult.$resultString = extractJsonBlock($ongoingTaskResult.$resultString || '');
|
|
6257
6456
|
}
|
|
@@ -6353,12 +6552,16 @@ async function executeAttempts(options) {
|
|
|
6353
6552
|
*/
|
|
6354
6553
|
|
|
6355
6554
|
/**
|
|
6356
|
-
*
|
|
6555
|
+
* Executes a pipeline task that requires mapping or iterating over subvalues of a parameter (such as rows in a CSV).
|
|
6556
|
+
* Handles format and subformat resolution, error handling, and progress reporting.
|
|
6557
|
+
*
|
|
6558
|
+
* @param options - Options for execution, including task details and progress callback.
|
|
6559
|
+
* @returns The result of the subvalue mapping or execution attempts.
|
|
6357
6560
|
*
|
|
6358
6561
|
* @private internal utility of `createPipelineExecutor`
|
|
6359
6562
|
*/
|
|
6360
6563
|
async function executeFormatSubvalues(options) {
|
|
6361
|
-
const { task, jokerParameterNames, parameters, priority, csvSettings, pipelineIdentification } = options;
|
|
6564
|
+
const { task, jokerParameterNames, parameters, priority, csvSettings, onProgress, pipelineIdentification } = options;
|
|
6362
6565
|
if (task.foreach === undefined) {
|
|
6363
6566
|
return /* not await */ executeAttempts(options);
|
|
6364
6567
|
}
|
|
@@ -6389,16 +6592,16 @@ async function executeFormatSubvalues(options) {
|
|
|
6389
6592
|
${block(pipelineIdentification)}
|
|
6390
6593
|
`));
|
|
6391
6594
|
}
|
|
6392
|
-
const
|
|
6393
|
-
if (
|
|
6595
|
+
const subvalueParser = formatDefinition.subvalueParsers.find((subvalueParser) => [subvalueParser.subvalueName, ...(subvalueParser.aliases || [])].includes(task.foreach.subformatName));
|
|
6596
|
+
if (subvalueParser === undefined) {
|
|
6394
6597
|
throw new UnexpectedError(
|
|
6395
6598
|
// <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
|
|
6396
6599
|
spaceTrim((block) => `
|
|
6397
6600
|
Unsupported subformat name "${task.foreach.subformatName}" for format "${task.foreach.formatName}"
|
|
6398
6601
|
|
|
6399
6602
|
Available subformat names for format "${formatDefinition.formatName}":
|
|
6400
|
-
${block(formatDefinition.
|
|
6401
|
-
.map((
|
|
6603
|
+
${block(formatDefinition.subvalueParsers
|
|
6604
|
+
.map((subvalueParser) => subvalueParser.subvalueName)
|
|
6402
6605
|
.map((subvalueName) => `- ${subvalueName}`)
|
|
6403
6606
|
.join('\n'))}
|
|
6404
6607
|
|
|
@@ -6412,53 +6615,83 @@ async function executeFormatSubvalues(options) {
|
|
|
6412
6615
|
formatSettings = csvSettings;
|
|
6413
6616
|
// <- TODO: [🤹♂️] More universal, make simmilar pattern for other formats for example \n vs \r\n in text
|
|
6414
6617
|
}
|
|
6415
|
-
const resultString = await
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6618
|
+
const resultString = await subvalueParser.mapValues({
|
|
6619
|
+
value: parameterValue,
|
|
6620
|
+
outputParameterName: task.foreach.outputSubparameterName,
|
|
6621
|
+
settings: formatSettings,
|
|
6622
|
+
onProgress(partialResultString) {
|
|
6623
|
+
return onProgress(Object.freeze({
|
|
6624
|
+
[task.resultingParameterName]: partialResultString,
|
|
6625
|
+
}));
|
|
6626
|
+
},
|
|
6627
|
+
async mapCallback(subparameters, index, length) {
|
|
6628
|
+
let mappedParameters;
|
|
6629
|
+
try {
|
|
6630
|
+
mappedParameters = mapAvailableToExpectedParameters({
|
|
6631
|
+
expectedParameters: Object.fromEntries(task.foreach.inputSubparameterNames.map((subparameterName) => [subparameterName, null])),
|
|
6632
|
+
availableParameters: subparameters,
|
|
6633
|
+
});
|
|
6428
6634
|
}
|
|
6429
|
-
|
|
6430
|
-
|
|
6635
|
+
catch (error) {
|
|
6636
|
+
if (!(error instanceof PipelineExecutionError)) {
|
|
6637
|
+
throw error;
|
|
6638
|
+
}
|
|
6639
|
+
const highLevelError = new PipelineExecutionError(spaceTrim((block) => `
|
|
6640
|
+
${error.message}
|
|
6431
6641
|
|
|
6432
|
-
|
|
6433
|
-
|
|
6642
|
+
This is error in FOREACH command when mapping ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
|
|
6643
|
+
You have probbably passed wrong data to pipeline or wrong data was generated which are processed by FOREACH command
|
|
6434
6644
|
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
|
|
6645
|
+
${block(pipelineIdentification)}
|
|
6646
|
+
`));
|
|
6647
|
+
if (length > BIG_DATASET_TRESHOLD) {
|
|
6648
|
+
console.error(highLevelError);
|
|
6649
|
+
return FAILED_VALUE_PLACEHOLDER;
|
|
6650
|
+
}
|
|
6651
|
+
throw highLevelError;
|
|
6652
|
+
}
|
|
6653
|
+
const allSubparameters = {
|
|
6654
|
+
...parameters,
|
|
6655
|
+
...mappedParameters,
|
|
6656
|
+
};
|
|
6657
|
+
Object.freeze(allSubparameters);
|
|
6658
|
+
try {
|
|
6659
|
+
const subresultString = await executeAttempts({
|
|
6660
|
+
...options,
|
|
6661
|
+
priority: priority + index,
|
|
6662
|
+
parameters: allSubparameters,
|
|
6663
|
+
pipelineIdentification: spaceTrim((block) => `
|
|
6664
|
+
${block(pipelineIdentification)}
|
|
6665
|
+
Subparameter index: ${index}
|
|
6666
|
+
`),
|
|
6667
|
+
});
|
|
6668
|
+
return subresultString;
|
|
6669
|
+
}
|
|
6670
|
+
catch (error) {
|
|
6671
|
+
if (length > BIG_DATASET_TRESHOLD) {
|
|
6672
|
+
console.error(spaceTrim((block) => `
|
|
6673
|
+
${error.message}
|
|
6674
|
+
|
|
6675
|
+
This is error in FOREACH command when processing ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
|
|
6676
|
+
|
|
6677
|
+
${block(pipelineIdentification)}
|
|
6678
|
+
`));
|
|
6679
|
+
return FAILED_VALUE_PLACEHOLDER;
|
|
6680
|
+
}
|
|
6681
|
+
throw error;
|
|
6682
|
+
}
|
|
6683
|
+
},
|
|
6455
6684
|
});
|
|
6456
6685
|
return resultString;
|
|
6457
6686
|
}
|
|
6458
6687
|
|
|
6459
6688
|
/**
|
|
6460
|
-
*
|
|
6689
|
+
* Returns the context for a given task, typically used to provide additional information or variables
|
|
6690
|
+
* required for the execution of the task within a pipeline. The context is returned as a string value
|
|
6691
|
+
* that may include markdown formatting.
|
|
6461
6692
|
*
|
|
6693
|
+
* @param task - The task for which the context is being generated. This should be a deeply immutable TaskJson object.
|
|
6694
|
+
* @returns The context as a string, formatted as markdown and parameter value.
|
|
6462
6695
|
* @private internal utility of `createPipelineExecutor`
|
|
6463
6696
|
*/
|
|
6464
6697
|
async function getContextForTask(task) {
|
|
@@ -6466,7 +6699,7 @@ async function getContextForTask(task) {
|
|
|
6466
6699
|
}
|
|
6467
6700
|
|
|
6468
6701
|
/**
|
|
6469
|
-
*
|
|
6702
|
+
* Retrieves example values or templates for a given task, used to guide or validate pipeline execution.
|
|
6470
6703
|
*
|
|
6471
6704
|
* @private internal utility of `createPipelineExecutor`
|
|
6472
6705
|
*/
|
|
@@ -6475,25 +6708,127 @@ async function getExamplesForTask(task) {
|
|
|
6475
6708
|
}
|
|
6476
6709
|
|
|
6477
6710
|
/**
|
|
6478
|
-
*
|
|
6711
|
+
* Computes the cosine similarity between two embedding vectors
|
|
6712
|
+
*
|
|
6713
|
+
* Note: This is helping function for RAG (retrieval-augmented generation)
|
|
6714
|
+
*
|
|
6715
|
+
* @param embeddingVector1
|
|
6716
|
+
* @param embeddingVector2
|
|
6717
|
+
* @returns Cosine similarity between the two vectors
|
|
6718
|
+
*
|
|
6719
|
+
* @public exported from `@promptbook/core`
|
|
6720
|
+
*/
|
|
6721
|
+
function computeCosineSimilarity(embeddingVector1, embeddingVector2) {
|
|
6722
|
+
if (embeddingVector1.length !== embeddingVector2.length) {
|
|
6723
|
+
throw new TypeError('Embedding vectors must have the same length');
|
|
6724
|
+
}
|
|
6725
|
+
const dotProduct = embeddingVector1.reduce((sum, value, index) => sum + value * embeddingVector2[index], 0);
|
|
6726
|
+
const magnitude1 = Math.sqrt(embeddingVector1.reduce((sum, value) => sum + value * value, 0));
|
|
6727
|
+
const magnitude2 = Math.sqrt(embeddingVector2.reduce((sum, value) => sum + value * value, 0));
|
|
6728
|
+
return 1 - dotProduct / (magnitude1 * magnitude2);
|
|
6729
|
+
}
|
|
6730
|
+
|
|
6731
|
+
/**
|
|
6732
|
+
*
|
|
6733
|
+
* @param knowledgePieces
|
|
6734
|
+
* @returns
|
|
6735
|
+
*
|
|
6736
|
+
* @private internal utility of `createPipelineExecutor`
|
|
6737
|
+
*/
|
|
6738
|
+
function knowledgePiecesToString(knowledgePieces) {
|
|
6739
|
+
return knowledgePieces
|
|
6740
|
+
.map((knowledgePiece) => {
|
|
6741
|
+
const { content } = knowledgePiece;
|
|
6742
|
+
return `- ${content}`;
|
|
6743
|
+
})
|
|
6744
|
+
.join('\n');
|
|
6745
|
+
// <- TODO: [🧠] Some smarter aggregation of knowledge pieces, single-line vs multi-line vs mixed
|
|
6746
|
+
}
|
|
6747
|
+
|
|
6748
|
+
/**
|
|
6749
|
+
* Retrieves the most relevant knowledge pieces for a given task using embedding-based similarity search.
|
|
6750
|
+
* This is where retrieval-augmented generation (RAG) is performed to enhance the task with external knowledge.
|
|
6479
6751
|
*
|
|
6480
6752
|
* @private internal utility of `createPipelineExecutor`
|
|
6481
6753
|
*/
|
|
6482
6754
|
async function getKnowledgeForTask(options) {
|
|
6483
|
-
const { preparedPipeline, task } = options;
|
|
6484
|
-
|
|
6485
|
-
|
|
6755
|
+
const { tools, preparedPipeline, task, parameters } = options;
|
|
6756
|
+
const firstKnowlegePiece = preparedPipeline.knowledgePieces[0];
|
|
6757
|
+
const firstKnowlegeIndex = firstKnowlegePiece === null || firstKnowlegePiece === void 0 ? void 0 : firstKnowlegePiece.index[0];
|
|
6758
|
+
// <- TODO: Do not use just first knowledge piece and first index to determine embedding model, use also keyword search
|
|
6759
|
+
if (firstKnowlegePiece === undefined || firstKnowlegeIndex === undefined) {
|
|
6760
|
+
return ''; // <- Note: Np knowledge present, return empty string
|
|
6761
|
+
}
|
|
6762
|
+
try {
|
|
6763
|
+
// TODO: [🚐] Make arrayable LLMs -> single LLM DRY
|
|
6764
|
+
const _llms = arrayableToArray(tools.llm);
|
|
6765
|
+
const llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools(..._llms);
|
|
6766
|
+
const taskEmbeddingPrompt = {
|
|
6767
|
+
title: 'Knowledge Search',
|
|
6768
|
+
modelRequirements: {
|
|
6769
|
+
modelVariant: 'EMBEDDING',
|
|
6770
|
+
modelName: firstKnowlegeIndex.modelName,
|
|
6771
|
+
},
|
|
6772
|
+
content: task.content,
|
|
6773
|
+
parameters,
|
|
6774
|
+
};
|
|
6775
|
+
const taskEmbeddingResult = await llmTools.callEmbeddingModel(taskEmbeddingPrompt);
|
|
6776
|
+
const knowledgePiecesWithRelevance = preparedPipeline.knowledgePieces.map((knowledgePiece) => {
|
|
6777
|
+
const { index } = knowledgePiece;
|
|
6778
|
+
const knowledgePieceIndex = index.find((i) => i.modelName === firstKnowlegeIndex.modelName);
|
|
6779
|
+
// <- TODO: Do not use just first knowledge piece and first index to determine embedding model
|
|
6780
|
+
if (knowledgePieceIndex === undefined) {
|
|
6781
|
+
return {
|
|
6782
|
+
content: knowledgePiece.content,
|
|
6783
|
+
relevance: 0,
|
|
6784
|
+
};
|
|
6785
|
+
}
|
|
6786
|
+
const relevance = computeCosineSimilarity(knowledgePieceIndex.position, taskEmbeddingResult.content);
|
|
6787
|
+
return {
|
|
6788
|
+
content: knowledgePiece.content,
|
|
6789
|
+
relevance,
|
|
6790
|
+
};
|
|
6791
|
+
});
|
|
6792
|
+
const knowledgePiecesSorted = knowledgePiecesWithRelevance.sort((a, b) => a.relevance - b.relevance);
|
|
6793
|
+
const knowledgePiecesLimited = knowledgePiecesSorted.slice(0, 5);
|
|
6794
|
+
console.log('!!! Embedding', {
|
|
6795
|
+
task,
|
|
6796
|
+
taskEmbeddingPrompt,
|
|
6797
|
+
taskEmbeddingResult,
|
|
6798
|
+
firstKnowlegePiece,
|
|
6799
|
+
firstKnowlegeIndex,
|
|
6800
|
+
knowledgePiecesWithRelevance,
|
|
6801
|
+
knowledgePiecesSorted,
|
|
6802
|
+
knowledgePiecesLimited,
|
|
6803
|
+
});
|
|
6804
|
+
return knowledgePiecesToString(knowledgePiecesLimited);
|
|
6805
|
+
}
|
|
6806
|
+
catch (error) {
|
|
6807
|
+
assertsError(error);
|
|
6808
|
+
console.error('Error in `getKnowledgeForTask`', error);
|
|
6809
|
+
// Note: If the LLM fails, just return all knowledge pieces
|
|
6810
|
+
return knowledgePiecesToString(preparedPipeline.knowledgePieces);
|
|
6811
|
+
}
|
|
6486
6812
|
}
|
|
6813
|
+
/**
|
|
6814
|
+
* TODO: !!!! Verify if this is working
|
|
6815
|
+
* TODO: [♨] Implement Better - use keyword search
|
|
6816
|
+
* TODO: [♨] Examples of values
|
|
6817
|
+
*/
|
|
6487
6818
|
|
|
6488
6819
|
/**
|
|
6489
|
-
*
|
|
6820
|
+
* Retrieves all reserved parameters for a given pipeline task, including context, knowledge, examples, and metadata.
|
|
6821
|
+
* Ensures all reserved parameters are defined and throws if any are missing.
|
|
6822
|
+
*
|
|
6823
|
+
* @param options - Options including tools, pipeline, task, and context.
|
|
6824
|
+
* @returns An object containing all reserved parameters for the task.
|
|
6490
6825
|
*
|
|
6491
6826
|
* @private internal utility of `createPipelineExecutor`
|
|
6492
6827
|
*/
|
|
6493
6828
|
async function getReservedParametersForTask(options) {
|
|
6494
|
-
const { preparedPipeline, task, pipelineIdentification } = options;
|
|
6829
|
+
const { tools, preparedPipeline, task, parameters, pipelineIdentification } = options;
|
|
6495
6830
|
const context = await getContextForTask(); // <- [🏍]
|
|
6496
|
-
const knowledge = await getKnowledgeForTask({ preparedPipeline, task });
|
|
6831
|
+
const knowledge = await getKnowledgeForTask({ tools, preparedPipeline, task, parameters });
|
|
6497
6832
|
const examples = await getExamplesForTask();
|
|
6498
6833
|
const currentDate = new Date().toISOString(); // <- TODO: [🧠][💩] Better
|
|
6499
6834
|
const modelName = RESERVED_PARAMETER_MISSING_VALUE;
|
|
@@ -6519,23 +6854,21 @@ async function getReservedParametersForTask(options) {
|
|
|
6519
6854
|
}
|
|
6520
6855
|
|
|
6521
6856
|
/**
|
|
6522
|
-
*
|
|
6857
|
+
* Executes a single task within a pipeline, handling parameter validation, error checking, and progress reporting.
|
|
6858
|
+
*
|
|
6859
|
+
* @param options - Options for execution, including the task, pipeline, parameters, and callbacks.
|
|
6860
|
+
* @returns The output parameters produced by the task.
|
|
6523
6861
|
*
|
|
6524
6862
|
* @private internal utility of `createPipelineExecutor`
|
|
6525
6863
|
*/
|
|
6526
6864
|
async function executeTask(options) {
|
|
6527
6865
|
const { currentTask, preparedPipeline, parametersToPass, tools, onProgress, $executionReport, pipelineIdentification, maxExecutionAttempts, maxParallelCount, csvSettings, isVerbose, rootDirname, cacheDirname, intermediateFilesStrategy, isAutoInstalled, isNotPreparedWarningSupressed, } = options;
|
|
6528
6866
|
const priority = preparedPipeline.tasks.length - preparedPipeline.tasks.indexOf(currentTask);
|
|
6529
|
-
await onProgress({
|
|
6530
|
-
outputParameters: {
|
|
6531
|
-
[currentTask.resultingParameterName]: '', // <- TODO: [🧠] What is the best value here?
|
|
6532
|
-
},
|
|
6533
|
-
});
|
|
6534
6867
|
// Note: Check consistency of used and dependent parameters which was also done in `validatePipeline`, but it’s good to doublecheck
|
|
6535
6868
|
const usedParameterNames = extractParameterNamesFromTask(currentTask);
|
|
6536
6869
|
const dependentParameterNames = new Set(currentTask.dependentParameterNames);
|
|
6537
6870
|
// TODO: [👩🏾🤝👩🏻] Use here `mapAvailableToExpectedParameters`
|
|
6538
|
-
if (union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)).size !== 0) {
|
|
6871
|
+
if (difference(union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)), new Set(RESERVED_PARAMETER_NAMES)).size !== 0) {
|
|
6539
6872
|
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
6540
6873
|
Dependent parameters are not consistent with used parameters:
|
|
6541
6874
|
|
|
@@ -6555,9 +6888,11 @@ async function executeTask(options) {
|
|
|
6555
6888
|
}
|
|
6556
6889
|
const definedParameters = Object.freeze({
|
|
6557
6890
|
...(await getReservedParametersForTask({
|
|
6891
|
+
tools,
|
|
6558
6892
|
preparedPipeline,
|
|
6559
6893
|
task: currentTask,
|
|
6560
6894
|
pipelineIdentification,
|
|
6895
|
+
parameters: parametersToPass,
|
|
6561
6896
|
})),
|
|
6562
6897
|
...parametersToPass,
|
|
6563
6898
|
});
|
|
@@ -6603,6 +6938,7 @@ async function executeTask(options) {
|
|
|
6603
6938
|
preparedPipeline,
|
|
6604
6939
|
tools,
|
|
6605
6940
|
$executionReport,
|
|
6941
|
+
onProgress,
|
|
6606
6942
|
pipelineIdentification,
|
|
6607
6943
|
maxExecutionAttempts,
|
|
6608
6944
|
maxParallelCount,
|
|
@@ -6630,7 +6966,8 @@ async function executeTask(options) {
|
|
|
6630
6966
|
*/
|
|
6631
6967
|
|
|
6632
6968
|
/**
|
|
6633
|
-
*
|
|
6969
|
+
* Filters and returns only the output parameters from the provided pipeline execution options.
|
|
6970
|
+
* Adds warnings for any expected output parameters that are missing.
|
|
6634
6971
|
*
|
|
6635
6972
|
* @private internal utility of `createPipelineExecutor`
|
|
6636
6973
|
*/
|
|
@@ -6655,9 +6992,12 @@ function filterJustOutputParameters(options) {
|
|
|
6655
6992
|
}
|
|
6656
6993
|
|
|
6657
6994
|
/**
|
|
6658
|
-
*
|
|
6995
|
+
* Executes an entire pipeline, resolving tasks in dependency order, handling errors, and reporting progress.
|
|
6996
|
+
*
|
|
6997
|
+
* Note: This is not a `PipelineExecutor` (which is bound to a single pipeline), but a utility function used by `createPipelineExecutor` to create a `PipelineExecutor`.
|
|
6659
6998
|
*
|
|
6660
|
-
*
|
|
6999
|
+
* @param options - Options for execution, including input parameters, pipeline, and callbacks.
|
|
7000
|
+
* @returns The result of the pipeline execution, including output parameters, errors, and usage statistics.
|
|
6661
7001
|
*
|
|
6662
7002
|
* @private internal utility of `createPipelineExecutor`
|
|
6663
7003
|
*/
|
|
@@ -6980,6 +7320,22 @@ function createPipelineExecutor(options) {
|
|
|
6980
7320
|
cacheDirname,
|
|
6981
7321
|
intermediateFilesStrategy,
|
|
6982
7322
|
isAutoInstalled,
|
|
7323
|
+
}).catch((error) => {
|
|
7324
|
+
assertsError(error);
|
|
7325
|
+
return exportJson({
|
|
7326
|
+
name: 'pipelineExecutorResult',
|
|
7327
|
+
message: `Unuccessful PipelineExecutorResult, last catch`,
|
|
7328
|
+
order: [],
|
|
7329
|
+
value: {
|
|
7330
|
+
isSuccessful: false,
|
|
7331
|
+
errors: [serializeError(error)],
|
|
7332
|
+
warnings: [],
|
|
7333
|
+
usage: UNCERTAIN_USAGE,
|
|
7334
|
+
executionReport: null,
|
|
7335
|
+
outputParameters: {},
|
|
7336
|
+
preparedPipeline,
|
|
7337
|
+
},
|
|
7338
|
+
});
|
|
6983
7339
|
});
|
|
6984
7340
|
};
|
|
6985
7341
|
const pipelineExecutor = (inputParameters) => createTask({
|
|
@@ -7040,27 +7396,48 @@ async function preparePersona(personaDescription, tools, options) {
|
|
|
7040
7396
|
pipeline: await collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-persona.book'),
|
|
7041
7397
|
tools,
|
|
7042
7398
|
});
|
|
7043
|
-
// TODO: [🚐] Make arrayable LLMs -> single LLM DRY
|
|
7044
7399
|
const _llms = arrayableToArray(tools.llm);
|
|
7045
7400
|
const llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools(..._llms);
|
|
7046
|
-
const availableModels = await llmTools.listModels()
|
|
7047
|
-
const availableModelNames = availableModels
|
|
7401
|
+
const availableModels = (await llmTools.listModels())
|
|
7048
7402
|
.filter(({ modelVariant }) => modelVariant === 'CHAT')
|
|
7049
|
-
.map(({ modelName }) =>
|
|
7050
|
-
|
|
7051
|
-
|
|
7403
|
+
.map(({ modelName, modelDescription }) => ({
|
|
7404
|
+
modelName,
|
|
7405
|
+
modelDescription,
|
|
7406
|
+
// <- Note: `modelTitle` and `modelVariant` is not relevant for this task
|
|
7407
|
+
}));
|
|
7408
|
+
const result = await preparePersonaExecutor({
|
|
7409
|
+
availableModels /* <- Note: Passing as JSON */,
|
|
7410
|
+
personaDescription,
|
|
7411
|
+
}).asPromise();
|
|
7052
7412
|
const { outputParameters } = result;
|
|
7053
|
-
const {
|
|
7054
|
-
|
|
7413
|
+
const { modelsRequirements: modelsRequirementsJson } = outputParameters;
|
|
7414
|
+
let modelsRequirementsUnchecked = jsonParse(modelsRequirementsJson);
|
|
7055
7415
|
if (isVerbose) {
|
|
7056
|
-
console.info(`PERSONA ${personaDescription}`,
|
|
7416
|
+
console.info(`PERSONA ${personaDescription}`, modelsRequirementsUnchecked);
|
|
7057
7417
|
}
|
|
7058
|
-
|
|
7059
|
-
|
|
7418
|
+
if (!Array.isArray(modelsRequirementsUnchecked)) {
|
|
7419
|
+
// <- TODO: Book should have syntax and system to enforce shape of JSON
|
|
7420
|
+
modelsRequirementsUnchecked = [modelsRequirementsUnchecked];
|
|
7421
|
+
/*
|
|
7422
|
+
throw new UnexpectedError(
|
|
7423
|
+
spaceTrim(
|
|
7424
|
+
(block) => `
|
|
7425
|
+
Invalid \`modelsRequirements\`:
|
|
7426
|
+
|
|
7427
|
+
\`\`\`json
|
|
7428
|
+
${block(JSON.stringify(modelsRequirementsUnchecked, null, 4))}
|
|
7429
|
+
\`\`\`
|
|
7430
|
+
`,
|
|
7431
|
+
),
|
|
7432
|
+
);
|
|
7433
|
+
*/
|
|
7434
|
+
}
|
|
7435
|
+
const modelsRequirements = modelsRequirementsUnchecked.map((modelRequirements) => ({
|
|
7060
7436
|
modelVariant: 'CHAT',
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
7437
|
+
...modelRequirements,
|
|
7438
|
+
}));
|
|
7439
|
+
return {
|
|
7440
|
+
modelsRequirements,
|
|
7064
7441
|
};
|
|
7065
7442
|
}
|
|
7066
7443
|
/**
|
|
@@ -7122,7 +7499,9 @@ function mimeTypeToExtension(value) {
|
|
|
7122
7499
|
}
|
|
7123
7500
|
|
|
7124
7501
|
/**
|
|
7125
|
-
*
|
|
7502
|
+
* Factory function that creates a handler for processing knowledge sources.
|
|
7503
|
+
* Provides standardized processing of different types of knowledge sources
|
|
7504
|
+
* across various scraper implementations.
|
|
7126
7505
|
*
|
|
7127
7506
|
* @public exported from `@promptbook/core`
|
|
7128
7507
|
*/
|
|
@@ -7229,7 +7608,7 @@ async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
|
|
|
7229
7608
|
> },
|
|
7230
7609
|
*/
|
|
7231
7610
|
async asJson() {
|
|
7232
|
-
return
|
|
7611
|
+
return jsonParse(await tools.fs.readFile(filename, 'utf-8'));
|
|
7233
7612
|
},
|
|
7234
7613
|
async asText() {
|
|
7235
7614
|
return await tools.fs.readFile(filename, 'utf-8');
|
|
@@ -7363,9 +7742,12 @@ TODO: [🧊] This is how it can look in future
|
|
|
7363
7742
|
*/
|
|
7364
7743
|
|
|
7365
7744
|
/**
|
|
7366
|
-
*
|
|
7745
|
+
* Prepares tasks by adding knowledge to the prompt and ensuring all necessary parameters are included.
|
|
7367
7746
|
*
|
|
7368
|
-
* @
|
|
7747
|
+
* @param tasks Sequence of tasks that are chained together to form a pipeline
|
|
7748
|
+
* @returns A promise that resolves to the prepared tasks.
|
|
7749
|
+
*
|
|
7750
|
+
* @private internal utility of `preparePipeline`
|
|
7369
7751
|
*/
|
|
7370
7752
|
async function prepareTasks(pipeline, tools, options) {
|
|
7371
7753
|
const { maxParallelCount = DEFAULT_MAX_PARALLEL_COUNT } = options;
|
|
@@ -7487,14 +7869,14 @@ async function preparePipeline(pipeline, tools, options) {
|
|
|
7487
7869
|
// TODO: [🖌][🧠] Implement some `mapAsync` function
|
|
7488
7870
|
const preparedPersonas = new Array(personas.length);
|
|
7489
7871
|
await forEachAsync(personas, { maxParallelCount /* <- TODO: [🪂] When there are subtasks, this maximul limit can be broken */ }, async (persona, index) => {
|
|
7490
|
-
const
|
|
7872
|
+
const { modelsRequirements } = await preparePersona(persona.description, { ...tools, llm: llmToolsWithUsage }, {
|
|
7491
7873
|
rootDirname,
|
|
7492
7874
|
maxParallelCount /* <- TODO: [🪂] */,
|
|
7493
7875
|
isVerbose,
|
|
7494
7876
|
});
|
|
7495
7877
|
const preparedPersona = {
|
|
7496
7878
|
...persona,
|
|
7497
|
-
|
|
7879
|
+
modelsRequirements,
|
|
7498
7880
|
preparationIds: [/* TODO: [🧊] -> */ currentPreparation.id],
|
|
7499
7881
|
// <- TODO: [🍙] Make some standard order of json properties
|
|
7500
7882
|
};
|
|
@@ -7883,7 +8265,7 @@ const sectionCommandParser = {
|
|
|
7883
8265
|
/**
|
|
7884
8266
|
* Parses the boilerplate command
|
|
7885
8267
|
*
|
|
7886
|
-
* Note:
|
|
8268
|
+
* Note: @@ This command is used as boilerplate for new commands - it should NOT be used in any `.book` file
|
|
7887
8269
|
*
|
|
7888
8270
|
* @see `documentationUrl` for more details
|
|
7889
8271
|
* @private within the commands folder
|
|
@@ -8271,11 +8653,11 @@ const expectCommandParser = {
|
|
|
8271
8653
|
};
|
|
8272
8654
|
|
|
8273
8655
|
/**
|
|
8274
|
-
*
|
|
8656
|
+
* Normalizes a given text to camelCase format.
|
|
8275
8657
|
*
|
|
8276
|
-
* @param text
|
|
8277
|
-
* @param _isFirstLetterCapital
|
|
8278
|
-
* @returns
|
|
8658
|
+
* @param text The text to be normalized.
|
|
8659
|
+
* @param _isFirstLetterCapital Whether the first letter should be capitalized.
|
|
8660
|
+
* @returns The camelCase formatted string.
|
|
8279
8661
|
* @example 'helloWorld'
|
|
8280
8662
|
* @example 'iLovePromptbook'
|
|
8281
8663
|
* @public exported from `@promptbook/utils`
|
|
@@ -8346,11 +8728,12 @@ function removeQuotes(text) {
|
|
|
8346
8728
|
}
|
|
8347
8729
|
|
|
8348
8730
|
/**
|
|
8349
|
-
* Function `validateParameterName` will
|
|
8731
|
+
* Function `validateParameterName` will normalize and validate a parameter name for use in pipelines.
|
|
8732
|
+
* It removes diacritics, emojis, and quotes, normalizes to camelCase, and checks for reserved names and invalid characters.
|
|
8350
8733
|
*
|
|
8351
|
-
* @param parameterName
|
|
8352
|
-
* @returns
|
|
8353
|
-
* @throws {ParseError}
|
|
8734
|
+
* @param parameterName The parameter name to validate and normalize.
|
|
8735
|
+
* @returns The validated and normalized parameter name.
|
|
8736
|
+
* @throws {ParseError} If the parameter name is empty, reserved, or contains invalid characters.
|
|
8354
8737
|
* @private within the repository
|
|
8355
8738
|
*/
|
|
8356
8739
|
function validateParameterName(parameterName) {
|
|
@@ -8420,8 +8803,6 @@ function validateParameterName(parameterName) {
|
|
|
8420
8803
|
/**
|
|
8421
8804
|
* Parses the foreach command
|
|
8422
8805
|
*
|
|
8423
|
-
* Note: @@@ This command is used as foreach for new commands - it should NOT be used in any `.book` file
|
|
8424
|
-
*
|
|
8425
8806
|
* @see `documentationUrl` for more details
|
|
8426
8807
|
* @public exported from `@promptbook/editable`
|
|
8427
8808
|
*/
|
|
@@ -8478,14 +8859,14 @@ const foreachCommandParser = {
|
|
|
8478
8859
|
`));
|
|
8479
8860
|
// <- TODO: [🏢] List all supported format names
|
|
8480
8861
|
}
|
|
8481
|
-
const
|
|
8482
|
-
if (
|
|
8862
|
+
const subvalueParser = formatDefinition.subvalueParsers.find((subvalueParser) => [subvalueParser.subvalueName, ...(subvalueParser.aliases || [])].includes(subformatName));
|
|
8863
|
+
if (subvalueParser === undefined) {
|
|
8483
8864
|
throw new ParseError(spaceTrim((block) => `
|
|
8484
8865
|
Unsupported subformat name "${subformatName}" for format "${formatName}"
|
|
8485
8866
|
|
|
8486
8867
|
Available subformat names for format "${formatDefinition.formatName}":
|
|
8487
|
-
${block(formatDefinition.
|
|
8488
|
-
.map((
|
|
8868
|
+
${block(formatDefinition.subvalueParsers
|
|
8869
|
+
.map((subvalueParser) => subvalueParser.subvalueName)
|
|
8489
8870
|
.map((subvalueName) => `- ${subvalueName}`)
|
|
8490
8871
|
.join('\n'))}
|
|
8491
8872
|
`));
|
|
@@ -8662,14 +9043,14 @@ const formatCommandParser = {
|
|
|
8662
9043
|
};
|
|
8663
9044
|
|
|
8664
9045
|
/**
|
|
8665
|
-
*
|
|
9046
|
+
* Chatbot form factor definition for conversational interfaces that interact with users in a chat-like manner.
|
|
8666
9047
|
*
|
|
8667
9048
|
* @public exported from `@promptbook/core`
|
|
8668
9049
|
*/
|
|
8669
9050
|
const ChatbotFormfactorDefinition = {
|
|
8670
9051
|
name: 'CHATBOT',
|
|
8671
9052
|
aliasNames: ['CHAT'],
|
|
8672
|
-
description:
|
|
9053
|
+
description: `A chatbot form factor for conversational user interfaces.`,
|
|
8673
9054
|
documentationUrl: `https://github.com/webgptorg/promptbook/discussions/174`,
|
|
8674
9055
|
pipelineInterface: {
|
|
8675
9056
|
inputParameters: [
|
|
@@ -8696,7 +9077,45 @@ const ChatbotFormfactorDefinition = {
|
|
|
8696
9077
|
};
|
|
8697
9078
|
|
|
8698
9079
|
/**
|
|
8699
|
-
*
|
|
9080
|
+
* Completion is formfactor that emulates completion models
|
|
9081
|
+
*
|
|
9082
|
+
* @public exported from `@promptbook/core`
|
|
9083
|
+
*/
|
|
9084
|
+
const CompletionFormfactorDefinition = {
|
|
9085
|
+
name: 'COMPLETION',
|
|
9086
|
+
description: `Completion is formfactor that emulates completion models`,
|
|
9087
|
+
documentationUrl: `https://github.com/webgptorg/promptbook/discussions/@@`,
|
|
9088
|
+
// <- TODO: https://github.com/webgptorg/promptbook/discussions/new?category=concepts
|
|
9089
|
+
// "🔠 Completion Formfactor"
|
|
9090
|
+
pipelineInterface: {
|
|
9091
|
+
inputParameters: [
|
|
9092
|
+
{
|
|
9093
|
+
name: 'inputText',
|
|
9094
|
+
description: `Input text to be completed`,
|
|
9095
|
+
isInput: true,
|
|
9096
|
+
isOutput: false,
|
|
9097
|
+
},
|
|
9098
|
+
{
|
|
9099
|
+
name: 'instructions',
|
|
9100
|
+
description: `Additional instructions for the model, for example the required length, empty by default`,
|
|
9101
|
+
isInput: true,
|
|
9102
|
+
isOutput: false,
|
|
9103
|
+
},
|
|
9104
|
+
],
|
|
9105
|
+
outputParameters: [
|
|
9106
|
+
{
|
|
9107
|
+
name: 'followingText',
|
|
9108
|
+
description: `Text that follows the input text`,
|
|
9109
|
+
isInput: false,
|
|
9110
|
+
isOutput: true,
|
|
9111
|
+
},
|
|
9112
|
+
],
|
|
9113
|
+
},
|
|
9114
|
+
};
|
|
9115
|
+
|
|
9116
|
+
/**
|
|
9117
|
+
* Generator form factor represents an application that generates content or data based on user input or predefined rules.
|
|
9118
|
+
* This form factor is used for apps that produce outputs, such as text, images, or other media, based on provided input.
|
|
8700
9119
|
*
|
|
8701
9120
|
* @public exported from `@promptbook/core`
|
|
8702
9121
|
*/
|
|
@@ -8725,7 +9144,7 @@ const GeneratorFormfactorDefinition = {
|
|
|
8725
9144
|
};
|
|
8726
9145
|
|
|
8727
9146
|
/**
|
|
8728
|
-
*
|
|
9147
|
+
* Pipeline interface which is equivalent to `any`
|
|
8729
9148
|
*
|
|
8730
9149
|
* @see https://github.com/webgptorg/promptbook/discussions/171
|
|
8731
9150
|
*
|
|
@@ -8740,13 +9159,13 @@ const GENERIC_PIPELINE_INTERFACE = {
|
|
|
8740
9159
|
*/
|
|
8741
9160
|
|
|
8742
9161
|
/**
|
|
8743
|
-
*
|
|
9162
|
+
* A generic pipeline
|
|
8744
9163
|
*
|
|
8745
9164
|
* @public exported from `@promptbook/core`
|
|
8746
9165
|
*/
|
|
8747
9166
|
const GenericFormfactorDefinition = {
|
|
8748
9167
|
name: 'GENERIC',
|
|
8749
|
-
description:
|
|
9168
|
+
description: `A generic pipeline`,
|
|
8750
9169
|
documentationUrl: `https://github.com/webgptorg/promptbook/discussions/173`,
|
|
8751
9170
|
pipelineInterface: GENERIC_PIPELINE_INTERFACE,
|
|
8752
9171
|
};
|
|
@@ -8781,17 +9200,20 @@ const ImageGeneratorFormfactorDefinition = {
|
|
|
8781
9200
|
};
|
|
8782
9201
|
|
|
8783
9202
|
/**
|
|
8784
|
-
* Matcher is form of app that
|
|
9203
|
+
* Matcher is form of app that evaluates (spreadsheet) content against defined criteria or patterns,
|
|
9204
|
+
* determining if it matches or meets specific requirements. Used for classification,
|
|
9205
|
+
* validation, filtering, and quality assessment of inputs.
|
|
8785
9206
|
*
|
|
8786
9207
|
* @public exported from `@promptbook/core`
|
|
8787
9208
|
*/
|
|
8788
9209
|
const MatcherFormfactorDefinition = {
|
|
8789
9210
|
name: 'EXPERIMENTAL_MATCHER',
|
|
8790
|
-
description:
|
|
9211
|
+
description: `An evaluation system that determines whether content meets specific criteria or patterns.
|
|
9212
|
+
Used for content validation, quality assessment, and intelligent filtering tasks. Currently in experimental phase.`,
|
|
8791
9213
|
documentationUrl: `https://github.com/webgptorg/promptbook/discussions/177`,
|
|
8792
9214
|
pipelineInterface: {
|
|
8793
9215
|
inputParameters: [
|
|
8794
|
-
/*
|
|
9216
|
+
/* Input parameters for content to be matched and criteria to match against */
|
|
8795
9217
|
{
|
|
8796
9218
|
name: 'nonce',
|
|
8797
9219
|
description: 'Just to prevent EXPERIMENTAL_MATCHER to be set as implicit formfactor',
|
|
@@ -8800,20 +9222,21 @@ const MatcherFormfactorDefinition = {
|
|
|
8800
9222
|
},
|
|
8801
9223
|
],
|
|
8802
9224
|
outputParameters: [
|
|
8803
|
-
/*
|
|
9225
|
+
/* Output parameters containing match results, confidence scores, and relevant metadata */
|
|
8804
9226
|
],
|
|
8805
9227
|
},
|
|
8806
9228
|
};
|
|
8807
9229
|
|
|
8808
9230
|
/**
|
|
8809
|
-
* Sheets is form of app that
|
|
9231
|
+
* Sheets is form of app that processes tabular data in CSV format, allowing transformation
|
|
9232
|
+
* and analysis of structured data through AI-powered operations
|
|
8810
9233
|
*
|
|
8811
9234
|
* @public exported from `@promptbook/core`
|
|
8812
9235
|
*/
|
|
8813
9236
|
const SheetsFormfactorDefinition = {
|
|
8814
9237
|
name: 'SHEETS',
|
|
8815
9238
|
aliasNames: ['SHEETS', 'SHEET'],
|
|
8816
|
-
description:
|
|
9239
|
+
description: `A formfactor for processing spreadsheet-like data in CSV format, enabling AI transformations on tabular data`,
|
|
8817
9240
|
documentationUrl: `https://github.com/webgptorg/promptbook/discussions/176`,
|
|
8818
9241
|
pipelineInterface: {
|
|
8819
9242
|
inputParameters: [
|
|
@@ -8836,13 +9259,16 @@ const SheetsFormfactorDefinition = {
|
|
|
8836
9259
|
};
|
|
8837
9260
|
|
|
8838
9261
|
/**
|
|
8839
|
-
* Translator is form of app that
|
|
9262
|
+
* Translator is form of app that transforms input text from one form to another,
|
|
9263
|
+
* such as language translation, style conversion, tone modification, or other text transformations.
|
|
8840
9264
|
*
|
|
8841
9265
|
* @public exported from `@promptbook/core`
|
|
8842
9266
|
*/
|
|
8843
9267
|
const TranslatorFormfactorDefinition = {
|
|
8844
9268
|
name: 'TRANSLATOR',
|
|
8845
|
-
description:
|
|
9269
|
+
description: `A text transformation system that converts input content into different forms,
|
|
9270
|
+
including language translations, paraphrasing, style conversions, and tone adjustments.
|
|
9271
|
+
This form factor takes one input and produces one transformed output.`,
|
|
8846
9272
|
documentationUrl: `https://github.com/webgptorg/promptbook/discussions/175`,
|
|
8847
9273
|
pipelineInterface: {
|
|
8848
9274
|
inputParameters: [
|
|
@@ -8879,6 +9305,8 @@ const FORMFACTOR_DEFINITIONS = [
|
|
|
8879
9305
|
MatcherFormfactorDefinition,
|
|
8880
9306
|
GeneratorFormfactorDefinition,
|
|
8881
9307
|
ImageGeneratorFormfactorDefinition,
|
|
9308
|
+
CompletionFormfactorDefinition,
|
|
9309
|
+
// <- [🛬] When making new formfactor, copy the _boilerplate and link it here
|
|
8882
9310
|
];
|
|
8883
9311
|
/**
|
|
8884
9312
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -8887,7 +9315,7 @@ const FORMFACTOR_DEFINITIONS = [
|
|
|
8887
9315
|
/**
|
|
8888
9316
|
* Parses the formfactor command
|
|
8889
9317
|
*
|
|
8890
|
-
* Note:
|
|
9318
|
+
* Note: This command is used as a formfactor for new commands and defines the app type format - it should NOT be used in any `.book` file
|
|
8891
9319
|
*
|
|
8892
9320
|
* @see `documentationUrl` for more details
|
|
8893
9321
|
* @public exported from `@promptbook/editable`
|
|
@@ -8909,7 +9337,7 @@ const formfactorCommandParser = {
|
|
|
8909
9337
|
/**
|
|
8910
9338
|
* Description of the FORMFACTOR command
|
|
8911
9339
|
*/
|
|
8912
|
-
description:
|
|
9340
|
+
description: `Specifies the application type and interface requirements that this promptbook should conform to`,
|
|
8913
9341
|
/**
|
|
8914
9342
|
* Link to documentation
|
|
8915
9343
|
*/
|
|
@@ -9052,8 +9480,7 @@ const jokerCommandParser = {
|
|
|
9052
9480
|
};
|
|
9053
9481
|
|
|
9054
9482
|
/**
|
|
9055
|
-
*
|
|
9056
|
-
*
|
|
9483
|
+
* @see {@link ModelVariant}
|
|
9057
9484
|
* @public exported from `@promptbook/core`
|
|
9058
9485
|
*/
|
|
9059
9486
|
const MODEL_VARIANTS = ['COMPLETION', 'CHAT', 'EMBEDDING' /* <- TODO [🏳] */ /* <- [🤖] */];
|
|
@@ -9485,10 +9912,10 @@ function $applyToTaskJson(command, $taskJson, $pipelineJson) {
|
|
|
9485
9912
|
}
|
|
9486
9913
|
|
|
9487
9914
|
/**
|
|
9488
|
-
*
|
|
9915
|
+
* Checks if the given value is a valid JavaScript identifier name.
|
|
9489
9916
|
*
|
|
9490
|
-
* @param javascriptName
|
|
9491
|
-
* @returns
|
|
9917
|
+
* @param javascriptName The value to check for JavaScript identifier validity.
|
|
9918
|
+
* @returns `true` if the value is a valid JavaScript name, false otherwise.
|
|
9492
9919
|
* @public exported from `@promptbook/utils`
|
|
9493
9920
|
*/
|
|
9494
9921
|
function isValidJavascriptName(javascriptName) {
|
|
@@ -9968,7 +10395,10 @@ function parseCommand(raw, usagePlace) {
|
|
|
9968
10395
|
`));
|
|
9969
10396
|
}
|
|
9970
10397
|
/**
|
|
9971
|
-
*
|
|
10398
|
+
* Generates a markdown-formatted message listing all supported commands
|
|
10399
|
+
* with their descriptions and documentation links
|
|
10400
|
+
*
|
|
10401
|
+
* @returns A formatted markdown string containing all available commands and their details
|
|
9972
10402
|
*/
|
|
9973
10403
|
function getSupportedCommandsMessage() {
|
|
9974
10404
|
return COMMANDS.flatMap(({ name, aliasNames, description, documentationUrl }) =>
|
|
@@ -9979,7 +10409,10 @@ function getSupportedCommandsMessage() {
|
|
|
9979
10409
|
]).join('\n');
|
|
9980
10410
|
}
|
|
9981
10411
|
/**
|
|
9982
|
-
*
|
|
10412
|
+
* Attempts to parse a command variant using the provided input parameters
|
|
10413
|
+
*
|
|
10414
|
+
* @param input Object containing command parsing information including raw command text and normalized values
|
|
10415
|
+
* @returns A parsed Command object if successful, or null if the command cannot be parsed
|
|
9983
10416
|
*/
|
|
9984
10417
|
function parseCommandVariant(input) {
|
|
9985
10418
|
const { commandNameRaw, usagePlace, normalized, args, raw, rawArgs } = input;
|
|
@@ -10026,7 +10459,7 @@ function parseCommandVariant(input) {
|
|
|
10026
10459
|
}
|
|
10027
10460
|
|
|
10028
10461
|
/**
|
|
10029
|
-
*
|
|
10462
|
+
* Extracts the interface (input and output parameters) from a pipeline.
|
|
10030
10463
|
*
|
|
10031
10464
|
* @deprecated https://github.com/webgptorg/promptbook/pull/186
|
|
10032
10465
|
* @see https://github.com/webgptorg/promptbook/discussions/171
|
|
@@ -10059,7 +10492,7 @@ function getPipelineInterface(pipeline) {
|
|
|
10059
10492
|
}
|
|
10060
10493
|
|
|
10061
10494
|
/**
|
|
10062
|
-
*
|
|
10495
|
+
* Checks if two pipeline interfaces are structurally identical.
|
|
10063
10496
|
*
|
|
10064
10497
|
* @deprecated https://github.com/webgptorg/promptbook/pull/186
|
|
10065
10498
|
* @see https://github.com/webgptorg/promptbook/discussions/171
|
|
@@ -10091,10 +10524,11 @@ function isPipelineInterfacesEqual(pipelineInterface1, pipelineInterface2) {
|
|
|
10091
10524
|
}
|
|
10092
10525
|
|
|
10093
10526
|
/**
|
|
10094
|
-
*
|
|
10527
|
+
* Checks if a given pipeline satisfies the requirements of a specified pipeline interface.
|
|
10095
10528
|
*
|
|
10096
10529
|
* @deprecated https://github.com/webgptorg/promptbook/pull/186
|
|
10097
10530
|
* @see https://github.com/webgptorg/promptbook/discussions/171
|
|
10531
|
+
* @returns `true` if the pipeline implements the interface, `false` otherwise.
|
|
10098
10532
|
*
|
|
10099
10533
|
* @public exported from `@promptbook/core`
|
|
10100
10534
|
*/
|
|
@@ -10280,7 +10714,8 @@ function removeMarkdownComments(content) {
|
|
|
10280
10714
|
}
|
|
10281
10715
|
|
|
10282
10716
|
/**
|
|
10283
|
-
*
|
|
10717
|
+
* Utility to determine if a pipeline string is in flat format.
|
|
10718
|
+
* A flat pipeline is a simple text without proper structure (headers, blocks, etc).
|
|
10284
10719
|
*
|
|
10285
10720
|
* @public exported from `@promptbook/editable`
|
|
10286
10721
|
*/
|
|
@@ -10301,7 +10736,10 @@ function isFlatPipeline(pipelineString) {
|
|
|
10301
10736
|
}
|
|
10302
10737
|
|
|
10303
10738
|
/**
|
|
10304
|
-
*
|
|
10739
|
+
* Converts a pipeline structure to its string representation.
|
|
10740
|
+
*
|
|
10741
|
+
* Transforms a flat, simple pipeline into a properly formatted pipeline string
|
|
10742
|
+
* with sections for title, prompt, and return statement.
|
|
10305
10743
|
*
|
|
10306
10744
|
* @public exported from `@promptbook/editable`
|
|
10307
10745
|
*/
|
|
@@ -10358,7 +10796,7 @@ function deflatePipeline(pipelineString) {
|
|
|
10358
10796
|
* Note: It can not work with html syntax and comments
|
|
10359
10797
|
*
|
|
10360
10798
|
* @param markdown any valid markdown
|
|
10361
|
-
* @returns
|
|
10799
|
+
* @returns An array of strings, each representing an individual list item found in the markdown
|
|
10362
10800
|
* @public exported from `@promptbook/markdown-utils`
|
|
10363
10801
|
*/
|
|
10364
10802
|
function extractAllListItemsFromMarkdown(markdown) {
|
|
@@ -11021,45 +11459,43 @@ async function compilePipeline(pipelineString, tools, options) {
|
|
|
11021
11459
|
*/
|
|
11022
11460
|
function renderPromptbookMermaid(pipelineJson, options) {
|
|
11023
11461
|
const { linkTask = () => null } = options || {};
|
|
11462
|
+
const MERMAID_PREFIX = 'pipeline_';
|
|
11463
|
+
const MERMAID_KNOWLEDGE_NAME = MERMAID_PREFIX + 'knowledge';
|
|
11464
|
+
const MERMAID_RESERVED_NAME = MERMAID_PREFIX + 'reserved';
|
|
11465
|
+
const MERMAID_INPUT_NAME = MERMAID_PREFIX + 'input';
|
|
11466
|
+
const MERMAID_OUTPUT_NAME = MERMAID_PREFIX + 'output';
|
|
11024
11467
|
const parameterNameToTaskName = (parameterName) => {
|
|
11468
|
+
if (parameterName === 'knowledge') {
|
|
11469
|
+
return MERMAID_KNOWLEDGE_NAME;
|
|
11470
|
+
}
|
|
11471
|
+
else if (RESERVED_PARAMETER_NAMES.includes(parameterName)) {
|
|
11472
|
+
return MERMAID_RESERVED_NAME;
|
|
11473
|
+
}
|
|
11025
11474
|
const parameter = pipelineJson.parameters.find((parameter) => parameter.name === parameterName);
|
|
11026
11475
|
if (!parameter) {
|
|
11027
11476
|
throw new UnexpectedError(`Could not find {${parameterName}}`);
|
|
11028
|
-
// <- TODO:
|
|
11477
|
+
// <- TODO: This causes problems when {knowledge} and other reserved parameters are used
|
|
11029
11478
|
}
|
|
11030
11479
|
if (parameter.isInput) {
|
|
11031
|
-
return
|
|
11480
|
+
return MERMAID_INPUT_NAME;
|
|
11032
11481
|
}
|
|
11033
11482
|
const task = pipelineJson.tasks.find((task) => task.resultingParameterName === parameterName);
|
|
11034
11483
|
if (!task) {
|
|
11035
11484
|
throw new Error(`Could not find task for {${parameterName}}`);
|
|
11036
11485
|
}
|
|
11037
|
-
return task.name || normalizeTo_camelCase('task-' + titleToName(task.title));
|
|
11486
|
+
return MERMAID_PREFIX + (task.name || normalizeTo_camelCase('task-' + titleToName(task.title)));
|
|
11038
11487
|
};
|
|
11039
|
-
const
|
|
11040
|
-
|
|
11041
|
-
%% 🔮 Tip: Open this on GitHub or in the VSCode website to see the Mermaid graph visually
|
|
11042
|
-
|
|
11043
|
-
flowchart LR
|
|
11044
|
-
subgraph "${pipelineJson.title}"
|
|
11045
|
-
|
|
11046
|
-
direction TB
|
|
11047
|
-
|
|
11048
|
-
input((Input)):::input
|
|
11049
|
-
${block(pipelineJson.tasks
|
|
11488
|
+
const inputAndIntermediateParametersMermaid = pipelineJson.tasks
|
|
11050
11489
|
.flatMap(({ title, dependentParameterNames, resultingParameterName }) => [
|
|
11051
11490
|
`${parameterNameToTaskName(resultingParameterName)}("${title}")`,
|
|
11052
11491
|
...dependentParameterNames.map((dependentParameterName) => `${parameterNameToTaskName(dependentParameterName)}--"{${dependentParameterName}}"-->${parameterNameToTaskName(resultingParameterName)}`),
|
|
11053
11492
|
])
|
|
11054
|
-
.join('\n')
|
|
11055
|
-
|
|
11056
|
-
${block(pipelineJson.parameters
|
|
11493
|
+
.join('\n');
|
|
11494
|
+
const outputParametersMermaid = pipelineJson.parameters
|
|
11057
11495
|
.filter(({ isOutput }) => isOutput)
|
|
11058
|
-
.map(({ name }) => `${parameterNameToTaskName(name)}--"{${name}}"
|
|
11059
|
-
.join('\n')
|
|
11060
|
-
|
|
11061
|
-
|
|
11062
|
-
${block(pipelineJson.tasks
|
|
11496
|
+
.map(({ name }) => `${parameterNameToTaskName(name)}--"{${name}}"-->${MERMAID_OUTPUT_NAME}`)
|
|
11497
|
+
.join('\n');
|
|
11498
|
+
const linksMermaid = pipelineJson.tasks
|
|
11063
11499
|
.map((task) => {
|
|
11064
11500
|
const link = linkTask(task);
|
|
11065
11501
|
if (link === null) {
|
|
@@ -11070,10 +11506,44 @@ function renderPromptbookMermaid(pipelineJson, options) {
|
|
|
11070
11506
|
return `click ${taskName} href "${href}" "${title}";`;
|
|
11071
11507
|
})
|
|
11072
11508
|
.filter((line) => line !== '')
|
|
11073
|
-
.join('\n')
|
|
11509
|
+
.join('\n');
|
|
11510
|
+
const interactionPointsMermaid = Object.entries({
|
|
11511
|
+
[MERMAID_INPUT_NAME]: 'Input',
|
|
11512
|
+
[MERMAID_OUTPUT_NAME]: 'Output',
|
|
11513
|
+
[MERMAID_RESERVED_NAME]: 'Other',
|
|
11514
|
+
[MERMAID_KNOWLEDGE_NAME]: 'Knowledge',
|
|
11515
|
+
})
|
|
11516
|
+
.filter(([MERMAID_NAME]) => (inputAndIntermediateParametersMermaid + outputParametersMermaid).includes(MERMAID_NAME))
|
|
11517
|
+
.map(([MERMAID_NAME, title]) => `${MERMAID_NAME}((${title})):::${MERMAID_NAME}`)
|
|
11518
|
+
.join('\n');
|
|
11519
|
+
const promptbookMermaid = spaceTrim$1((block) => `
|
|
11520
|
+
|
|
11521
|
+
%% 🔮 Tip: Open this on GitHub or in the VSCode website to see the Mermaid graph visually
|
|
11522
|
+
|
|
11523
|
+
flowchart LR
|
|
11524
|
+
subgraph "${pipelineJson.title}"
|
|
11525
|
+
|
|
11526
|
+
%% Basic configuration
|
|
11527
|
+
direction TB
|
|
11528
|
+
|
|
11529
|
+
%% Interaction points from pipeline to outside
|
|
11530
|
+
${block(interactionPointsMermaid)}
|
|
11531
|
+
|
|
11532
|
+
%% Input and intermediate parameters
|
|
11533
|
+
${block(inputAndIntermediateParametersMermaid)}
|
|
11074
11534
|
|
|
11075
|
-
|
|
11076
|
-
|
|
11535
|
+
|
|
11536
|
+
%% Output parameters
|
|
11537
|
+
${block(outputParametersMermaid)}
|
|
11538
|
+
|
|
11539
|
+
%% Links
|
|
11540
|
+
${block(linksMermaid)}
|
|
11541
|
+
|
|
11542
|
+
%% Styles
|
|
11543
|
+
classDef ${MERMAID_INPUT_NAME} color: grey;
|
|
11544
|
+
classDef ${MERMAID_OUTPUT_NAME} color: grey;
|
|
11545
|
+
classDef ${MERMAID_RESERVED_NAME} color: grey;
|
|
11546
|
+
classDef ${MERMAID_KNOWLEDGE_NAME} color: grey;
|
|
11077
11547
|
|
|
11078
11548
|
end;
|
|
11079
11549
|
|
|
@@ -11113,11 +11583,11 @@ function parseKeywordsFromString(input) {
|
|
|
11113
11583
|
}
|
|
11114
11584
|
|
|
11115
11585
|
/**
|
|
11116
|
-
*
|
|
11586
|
+
* Converts a name string into a URI-compatible format.
|
|
11117
11587
|
*
|
|
11118
|
-
* @param name
|
|
11119
|
-
* @returns
|
|
11120
|
-
* @example
|
|
11588
|
+
* @param name The string to be converted to a URI-compatible format.
|
|
11589
|
+
* @returns A URI-compatible string derived from the input name.
|
|
11590
|
+
* @example 'Hello World' -> 'hello-world'
|
|
11121
11591
|
* @public exported from `@promptbook/utils`
|
|
11122
11592
|
*/
|
|
11123
11593
|
function nameToUriPart(name) {
|
|
@@ -11131,11 +11601,11 @@ function nameToUriPart(name) {
|
|
|
11131
11601
|
}
|
|
11132
11602
|
|
|
11133
11603
|
/**
|
|
11134
|
-
*
|
|
11604
|
+
* Converts a given name into URI-compatible parts.
|
|
11135
11605
|
*
|
|
11136
|
-
* @param name
|
|
11137
|
-
* @returns
|
|
11138
|
-
* @example
|
|
11606
|
+
* @param name The name to be converted into URI parts.
|
|
11607
|
+
* @returns An array of URI-compatible parts derived from the name.
|
|
11608
|
+
* @example 'Example Name' -> ['example', 'name']
|
|
11139
11609
|
* @public exported from `@promptbook/utils`
|
|
11140
11610
|
*/
|
|
11141
11611
|
function nameToUriParts(name) {
|
|
@@ -12934,7 +13404,7 @@ function $initializeRunCommand(program) {
|
|
|
12934
13404
|
}
|
|
12935
13405
|
let inputParameters = {};
|
|
12936
13406
|
if (json) {
|
|
12937
|
-
inputParameters =
|
|
13407
|
+
inputParameters = jsonParse(json);
|
|
12938
13408
|
// <- TODO: Maybe check shape of passed JSON and if its valid parameters Record
|
|
12939
13409
|
}
|
|
12940
13410
|
// TODO: DRY [◽]
|
|
@@ -13111,10 +13581,10 @@ function $initializeRunCommand(program) {
|
|
|
13111
13581
|
console.info(colors.gray('--- Detailed Result ---'));
|
|
13112
13582
|
console.info({ isSuccessful, errors, warnings, outputParameters, executionReport });
|
|
13113
13583
|
}
|
|
13114
|
-
if (saveReport && saveReport.endsWith('.json')) {
|
|
13584
|
+
if (executionReport !== null && saveReport && saveReport.endsWith('.json')) {
|
|
13115
13585
|
await writeFile(saveReport, JSON.stringify(executionReport, null, 4) + '\n', 'utf-8');
|
|
13116
13586
|
}
|
|
13117
|
-
else if (saveReport && saveReport.endsWith('.md')) {
|
|
13587
|
+
else if (executionReport !== null && saveReport && saveReport.endsWith('.md')) {
|
|
13118
13588
|
const executionReportString = executionReportJsonToString(executionReport);
|
|
13119
13589
|
await writeFile(saveReport, executionReportString, 'utf-8');
|
|
13120
13590
|
}
|
|
@@ -13157,15 +13627,15 @@ function $initializeRunCommand(program) {
|
|
|
13157
13627
|
* TODO: [🖇] What about symlinks? Maybe flag --follow-symlinks
|
|
13158
13628
|
*/
|
|
13159
13629
|
|
|
13160
|
-
// TODO:
|
|
13161
|
-
// TODO:
|
|
13630
|
+
// TODO: [🥺] List running services from REMOTE_SERVER_URLS
|
|
13631
|
+
// TODO: [🥺] Import directly from YML
|
|
13162
13632
|
/**
|
|
13163
|
-
* @private
|
|
13633
|
+
* @private [🥺] Decide how to expose this
|
|
13164
13634
|
*/
|
|
13165
13635
|
const openapiJson = {
|
|
13166
13636
|
openapi: '3.0.0',
|
|
13167
13637
|
info: {
|
|
13168
|
-
title: 'Promptbook Remote Server API (
|
|
13638
|
+
title: 'Promptbook Remote Server API ([🥺] From YML)',
|
|
13169
13639
|
version: '1.0.0',
|
|
13170
13640
|
description: 'API documentation for the Promptbook Remote Server',
|
|
13171
13641
|
},
|
|
@@ -13177,6 +13647,13 @@ const openapiJson = {
|
|
|
13177
13647
|
responses: {
|
|
13178
13648
|
'200': {
|
|
13179
13649
|
description: 'Server details in markdown format.',
|
|
13650
|
+
content: {
|
|
13651
|
+
'text/markdown': {
|
|
13652
|
+
schema: {
|
|
13653
|
+
type: 'string',
|
|
13654
|
+
},
|
|
13655
|
+
},
|
|
13656
|
+
},
|
|
13180
13657
|
},
|
|
13181
13658
|
},
|
|
13182
13659
|
},
|
|
@@ -13207,13 +13684,22 @@ const openapiJson = {
|
|
|
13207
13684
|
},
|
|
13208
13685
|
},
|
|
13209
13686
|
responses: {
|
|
13210
|
-
'
|
|
13687
|
+
'201': {
|
|
13211
13688
|
description: 'Successful login',
|
|
13212
13689
|
content: {
|
|
13213
13690
|
'application/json': {
|
|
13214
13691
|
schema: {
|
|
13215
13692
|
type: 'object',
|
|
13216
13693
|
properties: {
|
|
13694
|
+
isSuccess: {
|
|
13695
|
+
type: 'boolean',
|
|
13696
|
+
},
|
|
13697
|
+
message: {
|
|
13698
|
+
type: 'string',
|
|
13699
|
+
},
|
|
13700
|
+
error: {
|
|
13701
|
+
type: 'object',
|
|
13702
|
+
},
|
|
13217
13703
|
identification: {
|
|
13218
13704
|
type: 'object',
|
|
13219
13705
|
},
|
|
@@ -13222,6 +13708,43 @@ const openapiJson = {
|
|
|
13222
13708
|
},
|
|
13223
13709
|
},
|
|
13224
13710
|
},
|
|
13711
|
+
'400': {
|
|
13712
|
+
description: 'Bad request or login failed',
|
|
13713
|
+
content: {
|
|
13714
|
+
'application/json': {
|
|
13715
|
+
schema: {
|
|
13716
|
+
type: 'object',
|
|
13717
|
+
properties: {
|
|
13718
|
+
error: {
|
|
13719
|
+
type: 'object',
|
|
13720
|
+
},
|
|
13721
|
+
},
|
|
13722
|
+
},
|
|
13723
|
+
},
|
|
13724
|
+
},
|
|
13725
|
+
},
|
|
13726
|
+
'401': {
|
|
13727
|
+
description: 'Authentication error',
|
|
13728
|
+
content: {
|
|
13729
|
+
'application/json': {
|
|
13730
|
+
schema: {
|
|
13731
|
+
type: 'object',
|
|
13732
|
+
properties: {
|
|
13733
|
+
isSuccess: {
|
|
13734
|
+
type: 'boolean',
|
|
13735
|
+
enum: [false],
|
|
13736
|
+
},
|
|
13737
|
+
message: {
|
|
13738
|
+
type: 'string',
|
|
13739
|
+
},
|
|
13740
|
+
error: {
|
|
13741
|
+
type: 'object',
|
|
13742
|
+
},
|
|
13743
|
+
},
|
|
13744
|
+
},
|
|
13745
|
+
},
|
|
13746
|
+
},
|
|
13747
|
+
},
|
|
13225
13748
|
},
|
|
13226
13749
|
},
|
|
13227
13750
|
},
|
|
@@ -13243,6 +13766,16 @@ const openapiJson = {
|
|
|
13243
13766
|
},
|
|
13244
13767
|
},
|
|
13245
13768
|
},
|
|
13769
|
+
'500': {
|
|
13770
|
+
description: 'No collection available',
|
|
13771
|
+
content: {
|
|
13772
|
+
'text/plain': {
|
|
13773
|
+
schema: {
|
|
13774
|
+
type: 'string',
|
|
13775
|
+
},
|
|
13776
|
+
},
|
|
13777
|
+
},
|
|
13778
|
+
},
|
|
13246
13779
|
},
|
|
13247
13780
|
},
|
|
13248
13781
|
},
|
|
@@ -13274,6 +13807,28 @@ const openapiJson = {
|
|
|
13274
13807
|
},
|
|
13275
13808
|
'404': {
|
|
13276
13809
|
description: 'Book not found.',
|
|
13810
|
+
content: {
|
|
13811
|
+
'application/json': {
|
|
13812
|
+
schema: {
|
|
13813
|
+
type: 'object',
|
|
13814
|
+
properties: {
|
|
13815
|
+
error: {
|
|
13816
|
+
type: 'object',
|
|
13817
|
+
},
|
|
13818
|
+
},
|
|
13819
|
+
},
|
|
13820
|
+
},
|
|
13821
|
+
},
|
|
13822
|
+
},
|
|
13823
|
+
'500': {
|
|
13824
|
+
description: 'No collection available',
|
|
13825
|
+
content: {
|
|
13826
|
+
'text/plain': {
|
|
13827
|
+
schema: {
|
|
13828
|
+
type: 'string',
|
|
13829
|
+
},
|
|
13830
|
+
},
|
|
13831
|
+
},
|
|
13277
13832
|
},
|
|
13278
13833
|
},
|
|
13279
13834
|
},
|
|
@@ -13291,11 +13846,174 @@ const openapiJson = {
|
|
|
13291
13846
|
type: 'array',
|
|
13292
13847
|
items: {
|
|
13293
13848
|
type: 'object',
|
|
13849
|
+
properties: {
|
|
13850
|
+
nonce: {
|
|
13851
|
+
type: 'string',
|
|
13852
|
+
},
|
|
13853
|
+
taskId: {
|
|
13854
|
+
type: 'string',
|
|
13855
|
+
},
|
|
13856
|
+
taskType: {
|
|
13857
|
+
type: 'string',
|
|
13858
|
+
},
|
|
13859
|
+
status: {
|
|
13860
|
+
type: 'string',
|
|
13861
|
+
},
|
|
13862
|
+
createdAt: {
|
|
13863
|
+
type: 'string',
|
|
13864
|
+
format: 'date-time',
|
|
13865
|
+
},
|
|
13866
|
+
updatedAt: {
|
|
13867
|
+
type: 'string',
|
|
13868
|
+
format: 'date-time',
|
|
13869
|
+
},
|
|
13870
|
+
},
|
|
13871
|
+
},
|
|
13872
|
+
},
|
|
13873
|
+
},
|
|
13874
|
+
},
|
|
13875
|
+
},
|
|
13876
|
+
},
|
|
13877
|
+
},
|
|
13878
|
+
},
|
|
13879
|
+
'/executions/last': {
|
|
13880
|
+
get: {
|
|
13881
|
+
summary: 'Get the last execution',
|
|
13882
|
+
description: 'Returns details of the last execution task.',
|
|
13883
|
+
responses: {
|
|
13884
|
+
'200': {
|
|
13885
|
+
description: 'The last execution task with full details.',
|
|
13886
|
+
content: {
|
|
13887
|
+
'application/json': {
|
|
13888
|
+
schema: {
|
|
13889
|
+
type: 'object',
|
|
13890
|
+
properties: {
|
|
13891
|
+
nonce: {
|
|
13892
|
+
type: 'string',
|
|
13893
|
+
},
|
|
13894
|
+
taskId: {
|
|
13895
|
+
type: 'string',
|
|
13896
|
+
},
|
|
13897
|
+
taskType: {
|
|
13898
|
+
type: 'string',
|
|
13899
|
+
},
|
|
13900
|
+
status: {
|
|
13901
|
+
type: 'string',
|
|
13902
|
+
},
|
|
13903
|
+
errors: {
|
|
13904
|
+
type: 'array',
|
|
13905
|
+
items: {
|
|
13906
|
+
type: 'object',
|
|
13907
|
+
},
|
|
13908
|
+
},
|
|
13909
|
+
warnings: {
|
|
13910
|
+
type: 'array',
|
|
13911
|
+
items: {
|
|
13912
|
+
type: 'object',
|
|
13913
|
+
},
|
|
13914
|
+
},
|
|
13915
|
+
createdAt: {
|
|
13916
|
+
type: 'string',
|
|
13917
|
+
format: 'date-time',
|
|
13918
|
+
},
|
|
13919
|
+
updatedAt: {
|
|
13920
|
+
type: 'string',
|
|
13921
|
+
format: 'date-time',
|
|
13922
|
+
},
|
|
13923
|
+
currentValue: {
|
|
13924
|
+
type: 'object',
|
|
13925
|
+
},
|
|
13926
|
+
},
|
|
13927
|
+
},
|
|
13928
|
+
},
|
|
13929
|
+
},
|
|
13930
|
+
},
|
|
13931
|
+
'404': {
|
|
13932
|
+
description: 'No execution tasks found.',
|
|
13933
|
+
content: {
|
|
13934
|
+
'text/plain': {
|
|
13935
|
+
schema: {
|
|
13936
|
+
type: 'string',
|
|
13937
|
+
},
|
|
13938
|
+
},
|
|
13939
|
+
},
|
|
13940
|
+
},
|
|
13941
|
+
},
|
|
13942
|
+
},
|
|
13943
|
+
},
|
|
13944
|
+
'/executions/{taskId}': {
|
|
13945
|
+
get: {
|
|
13946
|
+
summary: 'Get specific execution',
|
|
13947
|
+
description: 'Returns details of a specific execution task.',
|
|
13948
|
+
parameters: [
|
|
13949
|
+
{
|
|
13950
|
+
in: 'path',
|
|
13951
|
+
name: 'taskId',
|
|
13952
|
+
required: true,
|
|
13953
|
+
schema: {
|
|
13954
|
+
type: 'string',
|
|
13955
|
+
},
|
|
13956
|
+
description: 'The ID of the execution task to retrieve.',
|
|
13957
|
+
},
|
|
13958
|
+
],
|
|
13959
|
+
responses: {
|
|
13960
|
+
'200': {
|
|
13961
|
+
description: 'The execution task with full details.',
|
|
13962
|
+
content: {
|
|
13963
|
+
'application/json': {
|
|
13964
|
+
schema: {
|
|
13965
|
+
type: 'object',
|
|
13966
|
+
properties: {
|
|
13967
|
+
nonce: {
|
|
13968
|
+
type: 'string',
|
|
13969
|
+
},
|
|
13970
|
+
taskId: {
|
|
13971
|
+
type: 'string',
|
|
13972
|
+
},
|
|
13973
|
+
taskType: {
|
|
13974
|
+
type: 'string',
|
|
13975
|
+
},
|
|
13976
|
+
status: {
|
|
13977
|
+
type: 'string',
|
|
13978
|
+
},
|
|
13979
|
+
errors: {
|
|
13980
|
+
type: 'array',
|
|
13981
|
+
items: {
|
|
13982
|
+
type: 'object',
|
|
13983
|
+
},
|
|
13984
|
+
},
|
|
13985
|
+
warnings: {
|
|
13986
|
+
type: 'array',
|
|
13987
|
+
items: {
|
|
13988
|
+
type: 'object',
|
|
13989
|
+
},
|
|
13990
|
+
},
|
|
13991
|
+
createdAt: {
|
|
13992
|
+
type: 'string',
|
|
13993
|
+
format: 'date-time',
|
|
13994
|
+
},
|
|
13995
|
+
updatedAt: {
|
|
13996
|
+
type: 'string',
|
|
13997
|
+
format: 'date-time',
|
|
13998
|
+
},
|
|
13999
|
+
currentValue: {
|
|
14000
|
+
type: 'object',
|
|
14001
|
+
},
|
|
13294
14002
|
},
|
|
13295
14003
|
},
|
|
13296
14004
|
},
|
|
13297
14005
|
},
|
|
13298
14006
|
},
|
|
14007
|
+
'404': {
|
|
14008
|
+
description: 'Execution task not found.',
|
|
14009
|
+
content: {
|
|
14010
|
+
'text/plain': {
|
|
14011
|
+
schema: {
|
|
14012
|
+
type: 'string',
|
|
14013
|
+
},
|
|
14014
|
+
},
|
|
14015
|
+
},
|
|
14016
|
+
},
|
|
13299
14017
|
},
|
|
13300
14018
|
},
|
|
13301
14019
|
},
|
|
@@ -13312,12 +14030,19 @@ const openapiJson = {
|
|
|
13312
14030
|
properties: {
|
|
13313
14031
|
pipelineUrl: {
|
|
13314
14032
|
type: 'string',
|
|
14033
|
+
description: 'URL of the pipeline to execute',
|
|
14034
|
+
},
|
|
14035
|
+
book: {
|
|
14036
|
+
type: 'string',
|
|
14037
|
+
description: 'Alternative field for pipelineUrl',
|
|
13315
14038
|
},
|
|
13316
14039
|
inputParameters: {
|
|
13317
14040
|
type: 'object',
|
|
14041
|
+
description: 'Parameters for pipeline execution',
|
|
13318
14042
|
},
|
|
13319
14043
|
identification: {
|
|
13320
14044
|
type: 'object',
|
|
14045
|
+
description: 'User identification data',
|
|
13321
14046
|
},
|
|
13322
14047
|
},
|
|
13323
14048
|
},
|
|
@@ -13337,13 +14062,164 @@ const openapiJson = {
|
|
|
13337
14062
|
},
|
|
13338
14063
|
'400': {
|
|
13339
14064
|
description: 'Invalid input.',
|
|
14065
|
+
content: {
|
|
14066
|
+
'application/json': {
|
|
14067
|
+
schema: {
|
|
14068
|
+
type: 'object',
|
|
14069
|
+
properties: {
|
|
14070
|
+
error: {
|
|
14071
|
+
type: 'object',
|
|
14072
|
+
},
|
|
14073
|
+
},
|
|
14074
|
+
},
|
|
14075
|
+
},
|
|
14076
|
+
},
|
|
14077
|
+
},
|
|
14078
|
+
'404': {
|
|
14079
|
+
description: 'Pipeline not found.',
|
|
14080
|
+
content: {
|
|
14081
|
+
'text/plain': {
|
|
14082
|
+
schema: {
|
|
14083
|
+
type: 'string',
|
|
14084
|
+
},
|
|
14085
|
+
},
|
|
14086
|
+
},
|
|
14087
|
+
},
|
|
14088
|
+
},
|
|
14089
|
+
},
|
|
14090
|
+
},
|
|
14091
|
+
'/api-docs': {
|
|
14092
|
+
get: {
|
|
14093
|
+
summary: 'API documentation UI',
|
|
14094
|
+
description: 'Swagger UI for API documentation',
|
|
14095
|
+
responses: {
|
|
14096
|
+
'200': {
|
|
14097
|
+
description: 'HTML Swagger UI',
|
|
14098
|
+
},
|
|
14099
|
+
},
|
|
14100
|
+
},
|
|
14101
|
+
},
|
|
14102
|
+
'/swagger': {
|
|
14103
|
+
get: {
|
|
14104
|
+
summary: 'API documentation UI (alternative path)',
|
|
14105
|
+
description: 'Swagger UI for API documentation',
|
|
14106
|
+
responses: {
|
|
14107
|
+
'200': {
|
|
14108
|
+
description: 'HTML Swagger UI',
|
|
14109
|
+
},
|
|
14110
|
+
},
|
|
14111
|
+
},
|
|
14112
|
+
},
|
|
14113
|
+
'/openapi': {
|
|
14114
|
+
get: {
|
|
14115
|
+
summary: 'OpenAPI specification',
|
|
14116
|
+
description: 'Returns the OpenAPI JSON specification',
|
|
14117
|
+
responses: {
|
|
14118
|
+
'200': {
|
|
14119
|
+
description: 'OpenAPI specification',
|
|
14120
|
+
content: {
|
|
14121
|
+
'application/json': {
|
|
14122
|
+
schema: {
|
|
14123
|
+
type: 'object',
|
|
14124
|
+
},
|
|
14125
|
+
},
|
|
14126
|
+
},
|
|
14127
|
+
},
|
|
14128
|
+
},
|
|
14129
|
+
},
|
|
14130
|
+
},
|
|
14131
|
+
},
|
|
14132
|
+
components: {
|
|
14133
|
+
schemas: {
|
|
14134
|
+
Error: {
|
|
14135
|
+
type: 'object',
|
|
14136
|
+
properties: {
|
|
14137
|
+
error: {
|
|
14138
|
+
type: 'object',
|
|
14139
|
+
},
|
|
14140
|
+
},
|
|
14141
|
+
},
|
|
14142
|
+
ExecutionTaskSummary: {
|
|
14143
|
+
type: 'object',
|
|
14144
|
+
properties: {
|
|
14145
|
+
nonce: {
|
|
14146
|
+
type: 'string',
|
|
14147
|
+
},
|
|
14148
|
+
taskId: {
|
|
14149
|
+
type: 'string',
|
|
14150
|
+
},
|
|
14151
|
+
taskType: {
|
|
14152
|
+
type: 'string',
|
|
14153
|
+
},
|
|
14154
|
+
status: {
|
|
14155
|
+
type: 'string',
|
|
14156
|
+
},
|
|
14157
|
+
createdAt: {
|
|
14158
|
+
type: 'string',
|
|
14159
|
+
format: 'date-time',
|
|
14160
|
+
},
|
|
14161
|
+
updatedAt: {
|
|
14162
|
+
type: 'string',
|
|
14163
|
+
format: 'date-time',
|
|
14164
|
+
},
|
|
14165
|
+
},
|
|
14166
|
+
},
|
|
14167
|
+
ExecutionTaskFull: {
|
|
14168
|
+
type: 'object',
|
|
14169
|
+
properties: {
|
|
14170
|
+
nonce: {
|
|
14171
|
+
type: 'string',
|
|
14172
|
+
},
|
|
14173
|
+
taskId: {
|
|
14174
|
+
type: 'string',
|
|
14175
|
+
},
|
|
14176
|
+
taskType: {
|
|
14177
|
+
type: 'string',
|
|
14178
|
+
},
|
|
14179
|
+
status: {
|
|
14180
|
+
type: 'string',
|
|
14181
|
+
},
|
|
14182
|
+
errors: {
|
|
14183
|
+
type: 'array',
|
|
14184
|
+
items: {
|
|
14185
|
+
type: 'object',
|
|
14186
|
+
},
|
|
14187
|
+
},
|
|
14188
|
+
warnings: {
|
|
14189
|
+
type: 'array',
|
|
14190
|
+
items: {
|
|
14191
|
+
type: 'object',
|
|
14192
|
+
},
|
|
14193
|
+
},
|
|
14194
|
+
createdAt: {
|
|
14195
|
+
type: 'string',
|
|
14196
|
+
format: 'date-time',
|
|
14197
|
+
},
|
|
14198
|
+
updatedAt: {
|
|
14199
|
+
type: 'string',
|
|
14200
|
+
format: 'date-time',
|
|
14201
|
+
},
|
|
14202
|
+
currentValue: {
|
|
14203
|
+
type: 'object',
|
|
13340
14204
|
},
|
|
13341
14205
|
},
|
|
13342
14206
|
},
|
|
13343
14207
|
},
|
|
13344
14208
|
},
|
|
13345
|
-
|
|
13346
|
-
|
|
14209
|
+
tags: [
|
|
14210
|
+
{
|
|
14211
|
+
name: 'Books',
|
|
14212
|
+
description: 'Operations related to books and pipelines',
|
|
14213
|
+
},
|
|
14214
|
+
{
|
|
14215
|
+
name: 'Executions',
|
|
14216
|
+
description: 'Operations related to execution tasks',
|
|
14217
|
+
},
|
|
14218
|
+
{
|
|
14219
|
+
name: 'Authentication',
|
|
14220
|
+
description: 'Authentication operations',
|
|
14221
|
+
},
|
|
14222
|
+
],
|
|
13347
14223
|
};
|
|
13348
14224
|
/**
|
|
13349
14225
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -13417,7 +14293,7 @@ function startRemoteServer(options) {
|
|
|
13417
14293
|
response.setHeader('X-Powered-By', 'Promptbook engine');
|
|
13418
14294
|
next();
|
|
13419
14295
|
});
|
|
13420
|
-
// TODO:
|
|
14296
|
+
// TODO: [🥺] Expose openapiJson to consumer and also allow to add new routes
|
|
13421
14297
|
app.use(OpenApiValidator.middleware({
|
|
13422
14298
|
apiSpec: openapiJson,
|
|
13423
14299
|
ignorePaths(path) {
|
|
@@ -13714,6 +14590,7 @@ function startRemoteServer(options) {
|
|
|
13714
14590
|
promptResult = await llm.callCompletionModel(prompt);
|
|
13715
14591
|
break;
|
|
13716
14592
|
case 'EMBEDDING':
|
|
14593
|
+
console.log('!!! llm (EMBEDDING)', llm);
|
|
13717
14594
|
if (llm.callEmbeddingModel === undefined) {
|
|
13718
14595
|
// Note: [0] This check should not be a thing
|
|
13719
14596
|
throw new PipelineExecutionError(`Embedding model is not available`);
|
|
@@ -13988,7 +14865,7 @@ function $initializeTestCommand(program) {
|
|
|
13988
14865
|
}
|
|
13989
14866
|
}
|
|
13990
14867
|
if (filename.endsWith('.bookc')) {
|
|
13991
|
-
pipeline =
|
|
14868
|
+
pipeline = jsonParse(await readFile(filename, 'utf-8'));
|
|
13992
14869
|
}
|
|
13993
14870
|
else {
|
|
13994
14871
|
if (isVerbose) {
|
|
@@ -14111,9 +14988,11 @@ const _AnthropicClaudeMetadataRegistration = $llmToolsMetadataRegister.register(
|
|
|
14111
14988
|
packageName: '@promptbook/anthropic-claude',
|
|
14112
14989
|
className: 'AnthropicClaudeExecutionTools',
|
|
14113
14990
|
envVariables: ['ANTHROPIC_CLAUDE_API_KEY'],
|
|
14991
|
+
trustLevel: 'CLOSED',
|
|
14992
|
+
order: MODEL_ORDERS.TOP_TIER,
|
|
14114
14993
|
getBoilerplateConfiguration() {
|
|
14115
14994
|
return {
|
|
14116
|
-
title: 'Anthropic Claude
|
|
14995
|
+
title: 'Anthropic Claude',
|
|
14117
14996
|
packageName: '@promptbook/anthropic-claude',
|
|
14118
14997
|
className: 'AnthropicClaudeExecutionTools',
|
|
14119
14998
|
options: {
|
|
@@ -14155,7 +15034,7 @@ function computeUsage(value) {
|
|
|
14155
15034
|
/**
|
|
14156
15035
|
* List of available Anthropic Claude models with pricing
|
|
14157
15036
|
*
|
|
14158
|
-
* Note: Done at
|
|
15037
|
+
* Note: Done at 2025-05-06
|
|
14159
15038
|
*
|
|
14160
15039
|
* @see https://docs.anthropic.com/en/docs/models-overview
|
|
14161
15040
|
* @public exported from `@promptbook/anthropic-claude`
|
|
@@ -14169,8 +15048,8 @@ const ANTHROPIC_CLAUDE_MODELS = exportJson({
|
|
|
14169
15048
|
modelName: 'claude-3-5-sonnet-20240620',
|
|
14170
15049
|
modelDescription: 'Latest Claude model with great reasoning, coding, and language understanding capabilities. 200K context window. Optimized balance of intelligence and speed.',
|
|
14171
15050
|
pricing: {
|
|
14172
|
-
prompt: computeUsage(`$
|
|
14173
|
-
output: computeUsage(`$
|
|
15051
|
+
prompt: computeUsage(`$2.50 / 1M tokens`),
|
|
15052
|
+
output: computeUsage(`$12.50 / 1M tokens`),
|
|
14174
15053
|
},
|
|
14175
15054
|
},
|
|
14176
15055
|
{
|
|
@@ -14179,8 +15058,8 @@ const ANTHROPIC_CLAUDE_MODELS = exportJson({
|
|
|
14179
15058
|
modelName: 'claude-3-opus-20240229',
|
|
14180
15059
|
modelDescription: 'Most capable Claude model excelling at complex reasoning, coding, and detailed instruction following. 200K context window. Best for sophisticated tasks requiring nuanced understanding.',
|
|
14181
15060
|
pricing: {
|
|
14182
|
-
prompt: computeUsage(`$
|
|
14183
|
-
output: computeUsage(`$
|
|
15061
|
+
prompt: computeUsage(`$12.00 / 1M tokens`),
|
|
15062
|
+
output: computeUsage(`$60.00 / 1M tokens`),
|
|
14184
15063
|
},
|
|
14185
15064
|
},
|
|
14186
15065
|
{
|
|
@@ -14225,7 +15104,7 @@ const ANTHROPIC_CLAUDE_MODELS = exportJson({
|
|
|
14225
15104
|
},
|
|
14226
15105
|
{
|
|
14227
15106
|
modelVariant: 'CHAT',
|
|
14228
|
-
modelTitle: '
|
|
15107
|
+
modelTitle: 'Claude Instant 1.2',
|
|
14229
15108
|
modelName: 'claude-instant-1.2',
|
|
14230
15109
|
modelDescription: 'Older, faster Claude model optimized for high throughput applications. Lower cost but less capable than newer models. 100K context window.',
|
|
14231
15110
|
pricing: {
|
|
@@ -14239,8 +15118,8 @@ const ANTHROPIC_CLAUDE_MODELS = exportJson({
|
|
|
14239
15118
|
modelName: 'claude-3-7-sonnet-20250219',
|
|
14240
15119
|
modelDescription: 'Latest generation Claude model with advanced reasoning and language understanding. Enhanced capabilities over 3.5 with improved domain knowledge. 200K context window.',
|
|
14241
15120
|
pricing: {
|
|
14242
|
-
prompt: computeUsage(`$
|
|
14243
|
-
output: computeUsage(`$
|
|
15121
|
+
prompt: computeUsage(`$2.50 / 1M tokens`),
|
|
15122
|
+
output: computeUsage(`$12.50 / 1M tokens`),
|
|
14244
15123
|
},
|
|
14245
15124
|
},
|
|
14246
15125
|
{
|
|
@@ -14287,14 +15166,18 @@ function computeUsageCounts(content) {
|
|
|
14287
15166
|
/**
|
|
14288
15167
|
* Make UncertainNumber
|
|
14289
15168
|
*
|
|
14290
|
-
* @param value
|
|
15169
|
+
* @param value value of the uncertain number, if `NaN` or `undefined`, it will be set to 0 and `isUncertain=true`
|
|
15170
|
+
* @param isUncertain if `true`, the value is uncertain, otherwise depends on the value
|
|
14291
15171
|
*
|
|
14292
15172
|
* @private utility for initializating UncertainNumber
|
|
14293
15173
|
*/
|
|
14294
|
-
function uncertainNumber(value) {
|
|
15174
|
+
function uncertainNumber(value, isUncertain) {
|
|
14295
15175
|
if (value === null || value === undefined || Number.isNaN(value)) {
|
|
14296
15176
|
return UNCERTAIN_ZERO_VALUE;
|
|
14297
15177
|
}
|
|
15178
|
+
if (isUncertain === true) {
|
|
15179
|
+
return { value, isUncertain };
|
|
15180
|
+
}
|
|
14298
15181
|
return { value };
|
|
14299
15182
|
}
|
|
14300
15183
|
|
|
@@ -14649,9 +15532,11 @@ const _AzureOpenAiMetadataRegistration = $llmToolsMetadataRegister.register({
|
|
|
14649
15532
|
packageName: '@promptbook/azure-openai',
|
|
14650
15533
|
className: 'AzureOpenAiExecutionTools',
|
|
14651
15534
|
envVariables: ['AZUREOPENAI_RESOURCE_NAME', 'AZUREOPENAI_DEPLOYMENT_NAME', 'AZUREOPENAI_API_KEY'],
|
|
15535
|
+
trustLevel: 'CLOSED_BUSINESS',
|
|
15536
|
+
order: MODEL_ORDERS.NORMAL,
|
|
14652
15537
|
getBoilerplateConfiguration() {
|
|
14653
15538
|
return {
|
|
14654
|
-
title: 'Azure Open AI
|
|
15539
|
+
title: 'Azure Open AI',
|
|
14655
15540
|
packageName: '@promptbook/azure-openai',
|
|
14656
15541
|
className: 'AzureOpenAiExecutionTools',
|
|
14657
15542
|
options: {
|
|
@@ -14706,7 +15591,7 @@ const _AzureOpenAiMetadataRegistration = $llmToolsMetadataRegister.register({
|
|
|
14706
15591
|
/**
|
|
14707
15592
|
* List of available OpenAI models with pricing
|
|
14708
15593
|
*
|
|
14709
|
-
* Note: Done at
|
|
15594
|
+
* Note: Done at 2025-05-06
|
|
14710
15595
|
*
|
|
14711
15596
|
* @see https://platform.openai.com/docs/models/
|
|
14712
15597
|
* @see https://openai.com/api/pricing/
|
|
@@ -14735,7 +15620,7 @@ const OPENAI_MODELS = exportJson({
|
|
|
14735
15620
|
modelDescription: 'Legacy completion model with strong performance on text generation tasks. Optimized for complex instructions and longer outputs.',
|
|
14736
15621
|
pricing: {
|
|
14737
15622
|
prompt: computeUsage(`$2.00 / 1M tokens`),
|
|
14738
|
-
output: computeUsage(`$2.00 / 1M tokens`),
|
|
15623
|
+
output: computeUsage(`$2.00 / 1M tokens`),
|
|
14739
15624
|
},
|
|
14740
15625
|
},
|
|
14741
15626
|
/**/
|
|
@@ -14877,8 +15762,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
14877
15762
|
modelName: 'gpt-3.5-turbo',
|
|
14878
15763
|
modelDescription: 'Latest version of GPT-3.5 Turbo with improved performance and instruction following capabilities. Default 4K context window with options for 16K.',
|
|
14879
15764
|
pricing: {
|
|
14880
|
-
prompt: computeUsage(`$
|
|
14881
|
-
output: computeUsage(`$
|
|
15765
|
+
prompt: computeUsage(`$0.50 / 1M tokens`),
|
|
15766
|
+
output: computeUsage(`$1.50 / 1M tokens`),
|
|
14882
15767
|
},
|
|
14883
15768
|
},
|
|
14884
15769
|
/**/
|
|
@@ -14902,7 +15787,7 @@ const OPENAI_MODELS = exportJson({
|
|
|
14902
15787
|
modelDescription: 'Efficient legacy completion model with a good balance of performance and speed. Suitable for straightforward text generation tasks.',
|
|
14903
15788
|
pricing: {
|
|
14904
15789
|
prompt: computeUsage(`$0.40 / 1M tokens`),
|
|
14905
|
-
output: computeUsage(`$0.40 / 1M tokens`),
|
|
15790
|
+
output: computeUsage(`$0.40 / 1M tokens`),
|
|
14906
15791
|
},
|
|
14907
15792
|
},
|
|
14908
15793
|
/**/
|
|
@@ -14956,7 +15841,7 @@ const OPENAI_MODELS = exportJson({
|
|
|
14956
15841
|
modelDescription: 'Preview version of GPT-4 Turbo that points to the latest model version. Features improved instruction following, 128K token context window and lower latency.',
|
|
14957
15842
|
pricing: {
|
|
14958
15843
|
prompt: computeUsage(`$10.00 / 1M tokens`),
|
|
14959
|
-
output: computeUsage(`$30.00 / 1M tokens`),
|
|
15844
|
+
output: computeUsage(`$30.00 / 1M tokens`),
|
|
14960
15845
|
},
|
|
14961
15846
|
},
|
|
14962
15847
|
/**/
|
|
@@ -14967,7 +15852,7 @@ const OPENAI_MODELS = exportJson({
|
|
|
14967
15852
|
modelName: 'text-embedding-3-large',
|
|
14968
15853
|
modelDescription: "OpenAI's most capable text embedding model designed for high-quality embeddings for complex similarity tasks and information retrieval.",
|
|
14969
15854
|
pricing: {
|
|
14970
|
-
prompt: computeUsage(`$0.13
|
|
15855
|
+
prompt: computeUsage(`$0.13 / 1M tokens`),
|
|
14971
15856
|
// TODO: [🏏] Leverage the batch API @see https://platform.openai.com/docs/guides/batch
|
|
14972
15857
|
output: 0, // <- Note: [🆖] In Embedding models you dont pay for output
|
|
14973
15858
|
},
|
|
@@ -15060,8 +15945,8 @@ const OPENAI_MODELS = exportJson({
|
|
|
15060
15945
|
modelName: 'gpt-4o-mini',
|
|
15061
15946
|
modelDescription: 'Smaller, more cost-effective version of GPT-4o with good performance across text, vision, and audio tasks at reduced complexity.',
|
|
15062
15947
|
pricing: {
|
|
15063
|
-
prompt: computeUsage(`$
|
|
15064
|
-
output: computeUsage(`$
|
|
15948
|
+
prompt: computeUsage(`$0.15 / 1M tokens`),
|
|
15949
|
+
output: computeUsage(`$0.60 / 1M tokens`),
|
|
15065
15950
|
},
|
|
15066
15951
|
},
|
|
15067
15952
|
/**/
|
|
@@ -15107,10 +15992,10 @@ const OPENAI_MODELS = exportJson({
|
|
|
15107
15992
|
modelVariant: 'CHAT',
|
|
15108
15993
|
modelTitle: 'o1',
|
|
15109
15994
|
modelName: 'o1',
|
|
15995
|
+
modelDescription: "OpenAI's advanced reasoning model focused on logic and problem-solving. Designed for complex analytical tasks with rigorous step-by-step reasoning. 128K context window.",
|
|
15110
15996
|
pricing: {
|
|
15111
|
-
prompt: computeUsage(`$
|
|
15112
|
-
output: computeUsage(`$
|
|
15113
|
-
// <- TODO: !! Unsure, check the pricing
|
|
15997
|
+
prompt: computeUsage(`$15.00 / 1M tokens`),
|
|
15998
|
+
output: computeUsage(`$60.00 / 1M tokens`),
|
|
15114
15999
|
},
|
|
15115
16000
|
},
|
|
15116
16001
|
/**/
|
|
@@ -15119,7 +16004,7 @@ const OPENAI_MODELS = exportJson({
|
|
|
15119
16004
|
modelVariant: 'CHAT',
|
|
15120
16005
|
modelTitle: 'o3-mini',
|
|
15121
16006
|
modelName: 'o3-mini',
|
|
15122
|
-
modelDescription: '
|
|
16007
|
+
modelDescription: 'Cost-effective reasoning model optimized for academic and scientific problem-solving. Efficient performance on STEM tasks with deep mathematical and scientific knowledge. 128K context window.',
|
|
15123
16008
|
pricing: {
|
|
15124
16009
|
prompt: computeUsage(`$3.00 / 1M tokens`),
|
|
15125
16010
|
output: computeUsage(`$12.00 / 1M tokens`),
|
|
@@ -15186,6 +16071,10 @@ class AzureOpenAiExecutionTools {
|
|
|
15186
16071
|
* OpenAI Azure API client.
|
|
15187
16072
|
*/
|
|
15188
16073
|
this.client = null;
|
|
16074
|
+
// TODO: Allow configuring rate limits via options
|
|
16075
|
+
this.limiter = new Bottleneck({
|
|
16076
|
+
minTime: 60000 / (this.options.maxRequestsPerMinute || DEFAULT_MAX_REQUESTS_PER_MINUTE),
|
|
16077
|
+
});
|
|
15189
16078
|
}
|
|
15190
16079
|
get title() {
|
|
15191
16080
|
return 'Azure OpenAI';
|
|
@@ -15263,7 +16152,9 @@ class AzureOpenAiExecutionTools {
|
|
|
15263
16152
|
console.info(colors.bgWhite('messages'), JSON.stringify(messages, null, 4));
|
|
15264
16153
|
}
|
|
15265
16154
|
const rawRequest = [modelName, messages, modelSettings];
|
|
15266
|
-
const rawResponse = await this.
|
|
16155
|
+
const rawResponse = await this.limiter
|
|
16156
|
+
.schedule(() => this.withTimeout(client.getChatCompletions(...rawRequest)))
|
|
16157
|
+
.catch((error) => {
|
|
15267
16158
|
if (this.options.isVerbose) {
|
|
15268
16159
|
console.info(colors.bgRed('error'), error);
|
|
15269
16160
|
}
|
|
@@ -15359,7 +16250,9 @@ class AzureOpenAiExecutionTools {
|
|
|
15359
16250
|
[rawPromptContent],
|
|
15360
16251
|
modelSettings,
|
|
15361
16252
|
];
|
|
15362
|
-
const rawResponse = await this.
|
|
16253
|
+
const rawResponse = await this.limiter
|
|
16254
|
+
.schedule(() => this.withTimeout(client.getCompletions(...rawRequest)))
|
|
16255
|
+
.catch((error) => {
|
|
15363
16256
|
if (this.options.isVerbose) {
|
|
15364
16257
|
console.info(colors.bgRed('error'), error);
|
|
15365
16258
|
}
|
|
@@ -15499,9 +16392,11 @@ const _DeepseekMetadataRegistration = $llmToolsMetadataRegister.register({
|
|
|
15499
16392
|
packageName: '@promptbook/deepseek',
|
|
15500
16393
|
className: 'DeepseekExecutionTools',
|
|
15501
16394
|
envVariables: ['DEEPSEEK_GENERATIVE_AI_API_KEY'],
|
|
16395
|
+
trustLevel: 'UNTRUSTED',
|
|
16396
|
+
order: MODEL_ORDERS.NORMAL,
|
|
15502
16397
|
getBoilerplateConfiguration() {
|
|
15503
16398
|
return {
|
|
15504
|
-
title: 'Deepseek
|
|
16399
|
+
title: 'Deepseek',
|
|
15505
16400
|
packageName: '@promptbook/deepseek',
|
|
15506
16401
|
className: 'DeepseekExecutionTools',
|
|
15507
16402
|
options: {
|
|
@@ -15698,6 +16593,67 @@ function createExecutionToolsFromVercelProvider(options) {
|
|
|
15698
16593
|
};
|
|
15699
16594
|
}
|
|
15700
16595
|
|
|
16596
|
+
/**
|
|
16597
|
+
* List of available Deepseek models with descriptions
|
|
16598
|
+
*
|
|
16599
|
+
* Note: Done at 2025-05-06
|
|
16600
|
+
*
|
|
16601
|
+
* @see https://www.deepseek.com/models
|
|
16602
|
+
* @public exported from `@promptbook/deepseek`
|
|
16603
|
+
*/
|
|
16604
|
+
const DEEPSEEK_MODELS = exportJson({
|
|
16605
|
+
name: 'DEEPSEEK_MODELS',
|
|
16606
|
+
value: [
|
|
16607
|
+
{
|
|
16608
|
+
modelVariant: 'CHAT',
|
|
16609
|
+
modelTitle: 'Deepseek Chat',
|
|
16610
|
+
modelName: 'deepseek-chat',
|
|
16611
|
+
modelDescription: 'General-purpose language model with strong performance across conversation, reasoning, and content generation. 128K context window with excellent instruction following capabilities.',
|
|
16612
|
+
pricing: {
|
|
16613
|
+
prompt: computeUsage(`$0.80 / 1M tokens`),
|
|
16614
|
+
output: computeUsage(`$1.60 / 1M tokens`),
|
|
16615
|
+
},
|
|
16616
|
+
},
|
|
16617
|
+
{
|
|
16618
|
+
modelVariant: 'CHAT',
|
|
16619
|
+
modelTitle: 'Deepseek Reasoner',
|
|
16620
|
+
modelName: 'deepseek-reasoner',
|
|
16621
|
+
modelDescription: 'Specialized model focused on complex reasoning tasks like mathematical problem-solving and logical analysis. Enhanced step-by-step reasoning with explicit chain-of-thought processes. 128K context window.',
|
|
16622
|
+
pricing: {
|
|
16623
|
+
prompt: computeUsage(`$3.50 / 1M tokens`),
|
|
16624
|
+
output: computeUsage(`$7.00 / 1M tokens`),
|
|
16625
|
+
},
|
|
16626
|
+
},
|
|
16627
|
+
{
|
|
16628
|
+
modelVariant: 'CHAT',
|
|
16629
|
+
modelTitle: 'DeepSeek V3',
|
|
16630
|
+
modelName: 'deepseek-v3-0324',
|
|
16631
|
+
modelDescription: 'Advanced general-purpose model with improved reasoning, coding abilities, and multimodal understanding. Built on the latest DeepSeek architecture with enhanced knowledge representation.',
|
|
16632
|
+
pricing: {
|
|
16633
|
+
prompt: computeUsage(`$1.50 / 1M tokens`),
|
|
16634
|
+
output: computeUsage(`$3.00 / 1M tokens`),
|
|
16635
|
+
},
|
|
16636
|
+
},
|
|
16637
|
+
{
|
|
16638
|
+
modelVariant: 'CHAT',
|
|
16639
|
+
modelTitle: 'DeepSeek R1',
|
|
16640
|
+
modelName: 'deepseek-r1',
|
|
16641
|
+
modelDescription: 'Research-focused model optimized for scientific problem-solving and analytical tasks. Excellent performance on tasks requiring domain-specific expertise and critical thinking.',
|
|
16642
|
+
pricing: {
|
|
16643
|
+
prompt: computeUsage(`$5.00 / 1M tokens`),
|
|
16644
|
+
output: computeUsage(`$10.00 / 1M tokens`),
|
|
16645
|
+
},
|
|
16646
|
+
},
|
|
16647
|
+
// <- [🕕]
|
|
16648
|
+
],
|
|
16649
|
+
});
|
|
16650
|
+
/**
|
|
16651
|
+
* TODO: [🧠] Add information about context window sizes, capabilities, and relative performance characteristics
|
|
16652
|
+
* TODO: [🎰] Some mechanism to auto-update available models
|
|
16653
|
+
* TODO: [🧠] Verify pricing information is current with Deepseek's official documentation
|
|
16654
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
16655
|
+
*/
|
|
16656
|
+
|
|
15701
16657
|
/**
|
|
15702
16658
|
* Execution Tools for calling Deepseek API.
|
|
15703
16659
|
*
|
|
@@ -15719,18 +16675,7 @@ const createDeepseekExecutionTools = Object.assign((options) => {
|
|
|
15719
16675
|
title: 'Deepseek',
|
|
15720
16676
|
description: 'Implementation of Deepseek models',
|
|
15721
16677
|
vercelProvider: deepseekVercelProvider,
|
|
15722
|
-
availableModels:
|
|
15723
|
-
{
|
|
15724
|
-
modelName: 'deepseek-chat',
|
|
15725
|
-
modelVariant: 'CHAT',
|
|
15726
|
-
},
|
|
15727
|
-
{
|
|
15728
|
-
modelName: 'deepseek-reasoner',
|
|
15729
|
-
modelVariant: 'CHAT',
|
|
15730
|
-
},
|
|
15731
|
-
// <- [🕕]
|
|
15732
|
-
// <- TODO: How picking of the default model looks like in `createExecutionToolsFromVercelProvider`
|
|
15733
|
-
],
|
|
16678
|
+
availableModels: DEEPSEEK_MODELS,
|
|
15734
16679
|
...options,
|
|
15735
16680
|
});
|
|
15736
16681
|
}, {
|
|
@@ -15770,9 +16715,11 @@ const _GoogleMetadataRegistration = $llmToolsMetadataRegister.register({
|
|
|
15770
16715
|
packageName: '@promptbook/google',
|
|
15771
16716
|
className: 'GoogleExecutionTools',
|
|
15772
16717
|
envVariables: ['GOOGLE_GENERATIVE_AI_API_KEY'],
|
|
16718
|
+
trustLevel: 'CLOSED',
|
|
16719
|
+
order: MODEL_ORDERS.NORMAL,
|
|
15773
16720
|
getBoilerplateConfiguration() {
|
|
15774
16721
|
return {
|
|
15775
|
-
title: 'Google Gemini
|
|
16722
|
+
title: 'Google Gemini',
|
|
15776
16723
|
packageName: '@promptbook/google',
|
|
15777
16724
|
className: 'GoogleExecutionTools',
|
|
15778
16725
|
options: {
|
|
@@ -15805,6 +16752,173 @@ const _GoogleMetadataRegistration = $llmToolsMetadataRegister.register({
|
|
|
15805
16752
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
15806
16753
|
*/
|
|
15807
16754
|
|
|
16755
|
+
/**
|
|
16756
|
+
* List of available Google models with descriptions
|
|
16757
|
+
*
|
|
16758
|
+
* Note: Done at 2025-05-06
|
|
16759
|
+
*
|
|
16760
|
+
* @see https://ai.google.dev/models/gemini
|
|
16761
|
+
* @public exported from `@promptbook/google`
|
|
16762
|
+
*/
|
|
16763
|
+
const GOOGLE_MODELS = exportJson({
|
|
16764
|
+
name: 'GOOGLE_MODELS',
|
|
16765
|
+
value: [
|
|
16766
|
+
{
|
|
16767
|
+
modelVariant: 'CHAT',
|
|
16768
|
+
modelTitle: 'Gemini 2.5 Pro',
|
|
16769
|
+
modelName: 'gemini-2.5-pro-preview-03-25',
|
|
16770
|
+
modelDescription: 'Latest advanced multimodal model with exceptional reasoning, tool use, and instruction following. 1M token context window with improved vision capabilities for complex visual tasks.',
|
|
16771
|
+
pricing: {
|
|
16772
|
+
prompt: computeUsage(`$8.00 / 1M tokens`),
|
|
16773
|
+
output: computeUsage(`$24.00 / 1M tokens`),
|
|
16774
|
+
},
|
|
16775
|
+
},
|
|
16776
|
+
{
|
|
16777
|
+
modelVariant: 'CHAT',
|
|
16778
|
+
modelTitle: 'Gemini 2.0 Flash',
|
|
16779
|
+
modelName: 'gemini-2.0-flash',
|
|
16780
|
+
modelDescription: 'Fast, efficient model optimized for rapid response times. Good balance between performance and cost, with strong capabilities across text, code, and reasoning tasks. 128K context window.',
|
|
16781
|
+
pricing: {
|
|
16782
|
+
prompt: computeUsage(`$0.35 / 1M tokens`),
|
|
16783
|
+
output: computeUsage(`$1.05 / 1M tokens`),
|
|
16784
|
+
},
|
|
16785
|
+
},
|
|
16786
|
+
{
|
|
16787
|
+
modelVariant: 'CHAT',
|
|
16788
|
+
modelTitle: 'Gemini 2.0 Flash Lite',
|
|
16789
|
+
modelName: 'gemini-2.0-flash-lite',
|
|
16790
|
+
modelDescription: 'Streamlined version of Gemini 2.0 Flash, designed for extremely low-latency applications and edge deployments. Optimized for efficiency while maintaining core capabilities.',
|
|
16791
|
+
pricing: {
|
|
16792
|
+
prompt: computeUsage(`$0.20 / 1M tokens`),
|
|
16793
|
+
output: computeUsage(`$0.60 / 1M tokens`),
|
|
16794
|
+
},
|
|
16795
|
+
},
|
|
16796
|
+
{
|
|
16797
|
+
modelVariant: 'CHAT',
|
|
16798
|
+
modelTitle: 'Gemini 2.0 Flash Thinking',
|
|
16799
|
+
modelName: 'gemini-2.0-flash-thinking-exp-01-21',
|
|
16800
|
+
modelDescription: 'Experimental model focused on enhanced reasoning with explicit chain-of-thought processes. Designed for tasks requiring structured thinking and problem-solving approaches.',
|
|
16801
|
+
pricing: {
|
|
16802
|
+
prompt: computeUsage(`$0.35 / 1M tokens`),
|
|
16803
|
+
output: computeUsage(`$1.05 / 1M tokens`),
|
|
16804
|
+
},
|
|
16805
|
+
},
|
|
16806
|
+
{
|
|
16807
|
+
modelVariant: 'CHAT',
|
|
16808
|
+
modelTitle: 'Gemini 1.5 Flash',
|
|
16809
|
+
modelName: 'gemini-1.5-flash',
|
|
16810
|
+
modelDescription: 'Efficient model balancing speed and quality for general-purpose applications. 1M token context window with good multimodal capabilities and quick response times.',
|
|
16811
|
+
pricing: {
|
|
16812
|
+
prompt: computeUsage(`$0.25 / 1M tokens`),
|
|
16813
|
+
output: computeUsage(`$0.75 / 1M tokens`),
|
|
16814
|
+
},
|
|
16815
|
+
},
|
|
16816
|
+
{
|
|
16817
|
+
modelVariant: 'CHAT',
|
|
16818
|
+
modelTitle: 'Gemini 1.5 Flash Latest',
|
|
16819
|
+
modelName: 'gemini-1.5-flash-latest',
|
|
16820
|
+
modelDescription: 'Points to the latest version of Gemini 1.5 Flash, ensuring access to the most recent improvements and bug fixes while maintaining stable interfaces.',
|
|
16821
|
+
},
|
|
16822
|
+
{
|
|
16823
|
+
modelVariant: 'CHAT',
|
|
16824
|
+
modelTitle: 'Gemini 1.5 Flash 001',
|
|
16825
|
+
modelName: 'gemini-1.5-flash-001',
|
|
16826
|
+
modelDescription: 'First stable release of Gemini 1.5 Flash model with reliable performance characteristics for production applications. 1M token context window.',
|
|
16827
|
+
},
|
|
16828
|
+
{
|
|
16829
|
+
modelVariant: 'CHAT',
|
|
16830
|
+
modelTitle: 'Gemini 1.5 Flash 002',
|
|
16831
|
+
modelName: 'gemini-1.5-flash-002',
|
|
16832
|
+
modelDescription: 'Improved version of Gemini 1.5 Flash with enhanced instruction following and more consistent outputs. Refined for better application integration.',
|
|
16833
|
+
},
|
|
16834
|
+
{
|
|
16835
|
+
modelVariant: 'CHAT',
|
|
16836
|
+
modelTitle: 'Gemini 1.5 Flash Exp',
|
|
16837
|
+
modelName: 'gemini-1.5-flash-exp-0827',
|
|
16838
|
+
modelDescription: 'Experimental version of Gemini 1.5 Flash with new capabilities being tested. May offer improved performance but with potential behavior differences from stable releases.',
|
|
16839
|
+
},
|
|
16840
|
+
{
|
|
16841
|
+
modelVariant: 'CHAT',
|
|
16842
|
+
modelTitle: 'Gemini 1.5 Flash 8B',
|
|
16843
|
+
modelName: 'gemini-1.5-flash-8b',
|
|
16844
|
+
modelDescription: 'Compact 8B parameter model optimized for efficiency and deployment in resource-constrained environments. Good performance despite smaller size.',
|
|
16845
|
+
},
|
|
16846
|
+
{
|
|
16847
|
+
modelVariant: 'CHAT',
|
|
16848
|
+
modelTitle: 'Gemini 1.5 Flash 8B Latest',
|
|
16849
|
+
modelName: 'gemini-1.5-flash-8b-latest',
|
|
16850
|
+
modelDescription: 'Points to the most recent version of the compact 8B parameter model, providing latest improvements while maintaining a small footprint.',
|
|
16851
|
+
},
|
|
16852
|
+
{
|
|
16853
|
+
modelVariant: 'CHAT',
|
|
16854
|
+
modelTitle: 'Gemini 1.5 Flash 8B Exp',
|
|
16855
|
+
modelName: 'gemini-1.5-flash-8b-exp-0924',
|
|
16856
|
+
modelDescription: 'Experimental version of the 8B parameter model with new capabilities and optimizations being evaluated for future stable releases.',
|
|
16857
|
+
},
|
|
16858
|
+
{
|
|
16859
|
+
modelVariant: 'CHAT',
|
|
16860
|
+
modelTitle: 'Gemini 1.5 Flash 8B Exp',
|
|
16861
|
+
modelName: 'gemini-1.5-flash-8b-exp-0827',
|
|
16862
|
+
modelDescription: 'August experimental release of the efficient 8B parameter model with specific improvements to reasoning capabilities and response quality.',
|
|
16863
|
+
},
|
|
16864
|
+
{
|
|
16865
|
+
modelVariant: 'CHAT',
|
|
16866
|
+
modelTitle: 'Gemini 1.5 Pro Latest',
|
|
16867
|
+
modelName: 'gemini-1.5-pro-latest',
|
|
16868
|
+
modelDescription: 'Points to the most recent version of the flagship Gemini 1.5 Pro model, ensuring access to the latest capabilities and improvements.',
|
|
16869
|
+
pricing: {
|
|
16870
|
+
prompt: computeUsage(`$7.00 / 1M tokens`),
|
|
16871
|
+
output: computeUsage(`$21.00 / 1M tokens`),
|
|
16872
|
+
},
|
|
16873
|
+
},
|
|
16874
|
+
{
|
|
16875
|
+
modelVariant: 'CHAT',
|
|
16876
|
+
modelTitle: 'Gemini 1.5 Pro',
|
|
16877
|
+
modelName: 'gemini-1.5-pro',
|
|
16878
|
+
modelDescription: 'Flagship multimodal model with strong performance across text, code, vision, and audio tasks. 1M token context window with excellent reasoning capabilities.',
|
|
16879
|
+
pricing: {
|
|
16880
|
+
prompt: computeUsage(`$6.00 / 1M tokens`),
|
|
16881
|
+
output: computeUsage(`$18.00 / 1M tokens`),
|
|
16882
|
+
},
|
|
16883
|
+
},
|
|
16884
|
+
{
|
|
16885
|
+
modelVariant: 'CHAT',
|
|
16886
|
+
modelTitle: 'Gemini 1.5 Pro 001',
|
|
16887
|
+
modelName: 'gemini-1.5-pro-001',
|
|
16888
|
+
modelDescription: 'First stable release of Gemini 1.5 Pro with consistent performance characteristics and reliable behavior for production applications.',
|
|
16889
|
+
},
|
|
16890
|
+
{
|
|
16891
|
+
modelVariant: 'CHAT',
|
|
16892
|
+
modelTitle: 'Gemini 1.5 Pro 002',
|
|
16893
|
+
modelName: 'gemini-1.5-pro-002',
|
|
16894
|
+
modelDescription: 'Refined version of Gemini 1.5 Pro with improved instruction following, better multimodal understanding, and more consistent outputs.',
|
|
16895
|
+
},
|
|
16896
|
+
{
|
|
16897
|
+
modelVariant: 'CHAT',
|
|
16898
|
+
modelTitle: 'Gemini 1.5 Pro Exp',
|
|
16899
|
+
modelName: 'gemini-1.5-pro-exp-0827',
|
|
16900
|
+
modelDescription: 'Experimental version of Gemini 1.5 Pro with new capabilities and optimizations being tested before wider release. May offer improved performance.',
|
|
16901
|
+
},
|
|
16902
|
+
{
|
|
16903
|
+
modelVariant: 'CHAT',
|
|
16904
|
+
modelTitle: 'Gemini 1.0 Pro',
|
|
16905
|
+
modelName: 'gemini-1.0-pro',
|
|
16906
|
+
modelDescription: 'Original Gemini series foundation model with solid multimodal capabilities. 32K context window with good performance on text, code, and basic vision tasks.',
|
|
16907
|
+
pricing: {
|
|
16908
|
+
prompt: computeUsage(`$0.35 / 1M tokens`),
|
|
16909
|
+
output: computeUsage(`$1.05 / 1M tokens`),
|
|
16910
|
+
},
|
|
16911
|
+
},
|
|
16912
|
+
// <- [🕕]
|
|
16913
|
+
],
|
|
16914
|
+
});
|
|
16915
|
+
/**
|
|
16916
|
+
* TODO: [🧠] Add information about context window sizes, capabilities, and relative performance characteristics
|
|
16917
|
+
* TODO: [🎰] Some mechanism to auto-update available models
|
|
16918
|
+
* TODO: [🧠] Verify pricing information is current with Google's official documentation
|
|
16919
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
16920
|
+
*/
|
|
16921
|
+
|
|
15808
16922
|
/**
|
|
15809
16923
|
* Execution Tools for calling Google Gemini API.
|
|
15810
16924
|
*
|
|
@@ -15826,29 +16940,7 @@ const createGoogleExecutionTools = Object.assign((options) => {
|
|
|
15826
16940
|
title: 'Google',
|
|
15827
16941
|
description: 'Implementation of Google models',
|
|
15828
16942
|
vercelProvider: googleGeminiVercelProvider,
|
|
15829
|
-
availableModels:
|
|
15830
|
-
// TODO: [🕘] Maybe list models in same way as in other providers - in separate file with metadata
|
|
15831
|
-
'gemini-2.5-pro-preview-03-25',
|
|
15832
|
-
'gemini-2.0-flash',
|
|
15833
|
-
'gemini-2.0-flash-lite',
|
|
15834
|
-
'gemini-2.0-flash-thinking-exp-01-21',
|
|
15835
|
-
'gemini-1.5-flash',
|
|
15836
|
-
'gemini-1.5-flash-latest',
|
|
15837
|
-
'gemini-1.5-flash-001',
|
|
15838
|
-
'gemini-1.5-flash-002',
|
|
15839
|
-
'gemini-1.5-flash-exp-0827',
|
|
15840
|
-
'gemini-1.5-flash-8b',
|
|
15841
|
-
'gemini-1.5-flash-8b-latest',
|
|
15842
|
-
'gemini-1.5-flash-8b-exp-0924',
|
|
15843
|
-
'gemini-1.5-flash-8b-exp-0827',
|
|
15844
|
-
'gemini-1.5-pro-latest',
|
|
15845
|
-
'gemini-1.5-pro',
|
|
15846
|
-
'gemini-1.5-pro-001',
|
|
15847
|
-
'gemini-1.5-pro-002',
|
|
15848
|
-
'gemini-1.5-pro-exp-0827',
|
|
15849
|
-
'gemini-1.0-pro',
|
|
15850
|
-
// <- [🕕]
|
|
15851
|
-
].map((modelName) => ({ modelName, modelVariant: 'CHAT' })),
|
|
16943
|
+
availableModels: GOOGLE_MODELS,
|
|
15852
16944
|
...options,
|
|
15853
16945
|
});
|
|
15854
16946
|
}, {
|
|
@@ -15888,13 +16980,16 @@ const _OpenAiMetadataRegistration = $llmToolsMetadataRegister.register({
|
|
|
15888
16980
|
packageName: '@promptbook/openai',
|
|
15889
16981
|
className: 'OpenAiExecutionTools',
|
|
15890
16982
|
envVariables: ['OPENAI_API_KEY'],
|
|
16983
|
+
trustLevel: 'CLOSED',
|
|
16984
|
+
order: MODEL_ORDERS.TOP_TIER,
|
|
15891
16985
|
getBoilerplateConfiguration() {
|
|
15892
16986
|
return {
|
|
15893
|
-
title: 'Open AI
|
|
16987
|
+
title: 'Open AI',
|
|
15894
16988
|
packageName: '@promptbook/openai',
|
|
15895
16989
|
className: 'OpenAiExecutionTools',
|
|
15896
16990
|
options: {
|
|
15897
16991
|
apiKey: 'sk-',
|
|
16992
|
+
maxRequestsPerMinute: DEFAULT_MAX_REQUESTS_PER_MINUTE,
|
|
15898
16993
|
},
|
|
15899
16994
|
};
|
|
15900
16995
|
},
|
|
@@ -15914,9 +17009,9 @@ const _OpenAiMetadataRegistration = $llmToolsMetadataRegister.register({
|
|
|
15914
17009
|
},
|
|
15915
17010
|
});
|
|
15916
17011
|
/**
|
|
15917
|
-
*
|
|
17012
|
+
* Registration of the OpenAI Assistant metadata
|
|
15918
17013
|
*
|
|
15919
|
-
* Note: [🏐] Configurations registrations are done in
|
|
17014
|
+
* Note: [🏐] Configurations registrations are done in the metadata registration section, but the constructor registration is handled separately.
|
|
15920
17015
|
*
|
|
15921
17016
|
* @public exported from `@promptbook/core`
|
|
15922
17017
|
* @public exported from `@promptbook/wizzard`
|
|
@@ -15928,9 +17023,11 @@ const _OpenAiAssistantMetadataRegistration = $llmToolsMetadataRegister.register(
|
|
|
15928
17023
|
className: 'OpenAiAssistantExecutionTools',
|
|
15929
17024
|
envVariables: null,
|
|
15930
17025
|
// <- TODO: ['OPENAI_API_KEY', 'OPENAI_ASSISTANT_ID']
|
|
17026
|
+
trustLevel: 'CLOSED',
|
|
17027
|
+
order: MODEL_ORDERS.NORMAL,
|
|
15931
17028
|
getBoilerplateConfiguration() {
|
|
15932
17029
|
return {
|
|
15933
|
-
title: 'Open AI Assistant
|
|
17030
|
+
title: 'Open AI Assistant',
|
|
15934
17031
|
packageName: '@promptbook/openai',
|
|
15935
17032
|
className: 'OpenAiAssistantExecutionTools',
|
|
15936
17033
|
options: {
|
|
@@ -15975,20 +17072,39 @@ function computeOpenAiUsage(promptContent, // <- Note: Intentionally using [] to
|
|
|
15975
17072
|
resultContent, rawResponse) {
|
|
15976
17073
|
var _a, _b;
|
|
15977
17074
|
if (rawResponse.usage === undefined) {
|
|
17075
|
+
console.log('!!! computeOpenAiUsage', 'The usage is not defined in the response from OpenAI');
|
|
15978
17076
|
throw new PipelineExecutionError('The usage is not defined in the response from OpenAI');
|
|
15979
17077
|
}
|
|
15980
17078
|
if (((_a = rawResponse.usage) === null || _a === void 0 ? void 0 : _a.prompt_tokens) === undefined) {
|
|
17079
|
+
console.log('!!! computeOpenAiUsage', 'In OpenAI response `usage.prompt_tokens` not defined');
|
|
15981
17080
|
throw new PipelineExecutionError('In OpenAI response `usage.prompt_tokens` not defined');
|
|
15982
17081
|
}
|
|
15983
17082
|
const inputTokens = rawResponse.usage.prompt_tokens;
|
|
15984
17083
|
const outputTokens = ((_b = rawResponse.usage) === null || _b === void 0 ? void 0 : _b.completion_tokens) || 0;
|
|
15985
|
-
|
|
17084
|
+
let isUncertain = false;
|
|
17085
|
+
let modelInfo = OPENAI_MODELS.find((model) => model.modelName === rawResponse.model);
|
|
17086
|
+
if (modelInfo === undefined) {
|
|
17087
|
+
// Note: Model is not in the list of known models, fallback to the family of the models and mark price as uncertain
|
|
17088
|
+
modelInfo = OPENAI_MODELS.find((model) => (rawResponse.model || SALT_NONCE).startsWith(model.modelName));
|
|
17089
|
+
if (modelInfo !== undefined) {
|
|
17090
|
+
isUncertain = true;
|
|
17091
|
+
}
|
|
17092
|
+
}
|
|
17093
|
+
console.log('!!! computeOpenAiUsage', {
|
|
17094
|
+
inputTokens,
|
|
17095
|
+
outputTokens,
|
|
17096
|
+
rawResponse,
|
|
17097
|
+
'rawResponse.model': rawResponse.model,
|
|
17098
|
+
OPENAI_MODELS,
|
|
17099
|
+
resultContent,
|
|
17100
|
+
modelInfo,
|
|
17101
|
+
});
|
|
15986
17102
|
let price;
|
|
15987
17103
|
if (modelInfo === undefined || modelInfo.pricing === undefined) {
|
|
15988
17104
|
price = uncertainNumber();
|
|
15989
17105
|
}
|
|
15990
17106
|
else {
|
|
15991
|
-
price = uncertainNumber(inputTokens * modelInfo.pricing.prompt + outputTokens * modelInfo.pricing.output);
|
|
17107
|
+
price = uncertainNumber(inputTokens * modelInfo.pricing.prompt + outputTokens * modelInfo.pricing.output, isUncertain);
|
|
15992
17108
|
}
|
|
15993
17109
|
return {
|
|
15994
17110
|
price,
|
|
@@ -16023,6 +17139,10 @@ class OpenAiExecutionTools {
|
|
|
16023
17139
|
* OpenAI API client.
|
|
16024
17140
|
*/
|
|
16025
17141
|
this.client = null;
|
|
17142
|
+
// TODO: Allow configuring rate limits via options
|
|
17143
|
+
this.limiter = new Bottleneck({
|
|
17144
|
+
minTime: 60000 / (this.options.maxRequestsPerMinute || DEFAULT_MAX_REQUESTS_PER_MINUTE),
|
|
17145
|
+
});
|
|
16026
17146
|
}
|
|
16027
17147
|
get title() {
|
|
16028
17148
|
return 'OpenAI';
|
|
@@ -16126,7 +17246,9 @@ class OpenAiExecutionTools {
|
|
|
16126
17246
|
if (this.options.isVerbose) {
|
|
16127
17247
|
console.info(colors.bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));
|
|
16128
17248
|
}
|
|
16129
|
-
const rawResponse = await
|
|
17249
|
+
const rawResponse = await this.limiter
|
|
17250
|
+
.schedule(() => client.chat.completions.create(rawRequest))
|
|
17251
|
+
.catch((error) => {
|
|
16130
17252
|
assertsError(error);
|
|
16131
17253
|
if (this.options.isVerbose) {
|
|
16132
17254
|
console.info(colors.bgRed('error'), error);
|
|
@@ -16203,7 +17325,9 @@ class OpenAiExecutionTools {
|
|
|
16203
17325
|
if (this.options.isVerbose) {
|
|
16204
17326
|
console.info(colors.bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));
|
|
16205
17327
|
}
|
|
16206
|
-
const rawResponse = await
|
|
17328
|
+
const rawResponse = await this.limiter
|
|
17329
|
+
.schedule(() => client.completions.create(rawRequest))
|
|
17330
|
+
.catch((error) => {
|
|
16207
17331
|
assertsError(error);
|
|
16208
17332
|
if (this.options.isVerbose) {
|
|
16209
17333
|
console.info(colors.bgRed('error'), error);
|
|
@@ -16267,7 +17391,9 @@ class OpenAiExecutionTools {
|
|
|
16267
17391
|
if (this.options.isVerbose) {
|
|
16268
17392
|
console.info(colors.bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));
|
|
16269
17393
|
}
|
|
16270
|
-
const rawResponse = await
|
|
17394
|
+
const rawResponse = await this.limiter
|
|
17395
|
+
.schedule(() => client.embeddings.create(rawRequest))
|
|
17396
|
+
.catch((error) => {
|
|
16271
17397
|
assertsError(error);
|
|
16272
17398
|
if (this.options.isVerbose) {
|
|
16273
17399
|
console.info(colors.bgRed('error'), error);
|
|
@@ -16365,6 +17491,7 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
|
|
|
16365
17491
|
constructor(options) {
|
|
16366
17492
|
super(options);
|
|
16367
17493
|
this.assistantId = options.assistantId;
|
|
17494
|
+
// TODO: [👱] Make limiter same as in `OpenAiExecutionTools`
|
|
16368
17495
|
}
|
|
16369
17496
|
get title() {
|
|
16370
17497
|
return 'OpenAI Assistant';
|
|
@@ -16566,9 +17693,9 @@ const createOpenAiExecutionTools = Object.assign((options) => {
|
|
|
16566
17693
|
*/
|
|
16567
17694
|
const _OpenAiRegistration = $llmToolsRegister.register(createOpenAiExecutionTools);
|
|
16568
17695
|
/**
|
|
16569
|
-
*
|
|
17696
|
+
* Registration of the OpenAI Assistant provider
|
|
16570
17697
|
*
|
|
16571
|
-
* Note: [🏐] Configurations registrations are done in
|
|
17698
|
+
* Note: [🏐] Configurations registrations are done in register-constructor.ts BUT constructor register-constructor.ts
|
|
16572
17699
|
*
|
|
16573
17700
|
* @public exported from `@promptbook/openai`
|
|
16574
17701
|
* @public exported from `@promptbook/wizzard`
|
|
@@ -16581,9 +17708,8 @@ const _OpenAiAssistantRegistration = $llmToolsRegister.register(createOpenAiAssi
|
|
|
16581
17708
|
*/
|
|
16582
17709
|
|
|
16583
17710
|
/**
|
|
16584
|
-
*
|
|
16585
|
-
*
|
|
16586
|
-
* Note: It also checks if directory exists and creates it if not
|
|
17711
|
+
* Retrieves an intermediate source for a scraper based on the knowledge source.
|
|
17712
|
+
* Manages the caching and retrieval of intermediate scraper results for optimized performance.
|
|
16587
17713
|
*
|
|
16588
17714
|
* @private as internal utility for scrapers
|
|
16589
17715
|
*/
|
|
@@ -16810,14 +17936,14 @@ const boilerplateScraperMetadata = $deepFreeze({
|
|
|
16810
17936
|
packageName: '@promptbook/boilerplate',
|
|
16811
17937
|
className: 'BoilerplateScraper',
|
|
16812
17938
|
mimeTypes: [
|
|
16813
|
-
'
|
|
16814
|
-
// <- TODO:
|
|
17939
|
+
'@@/@@',
|
|
17940
|
+
// <- TODO: @@ Add compatible mime types with Boilerplate scraper
|
|
16815
17941
|
],
|
|
16816
|
-
documentationUrl: 'https://github.com/webgptorg/promptbook/discussions
|
|
17942
|
+
documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
|
|
16817
17943
|
isAvilableInBrowser: false,
|
|
16818
17944
|
// <- Note: [🌏] Only `MarkdownScraper` makes sense to be available in the browser, for scraping non-markdown sources in the browser use a remote server
|
|
16819
17945
|
requiredExecutables: [
|
|
16820
|
-
/*
|
|
17946
|
+
/* @@ 'Pandoc' */
|
|
16821
17947
|
],
|
|
16822
17948
|
}); /* <- Note: [🤛] */
|
|
16823
17949
|
/**
|
|
@@ -16835,7 +17961,7 @@ const _BoilerplateScraperMetadataRegistration = $scrapersMetadataRegister.regist
|
|
|
16835
17961
|
*/
|
|
16836
17962
|
|
|
16837
17963
|
/**
|
|
16838
|
-
* Scraper of
|
|
17964
|
+
* Scraper of @@ files
|
|
16839
17965
|
*
|
|
16840
17966
|
* @see `documentationUrl` for more details
|
|
16841
17967
|
* @public exported from `@promptbook/boilerplate`
|
|
@@ -16853,30 +17979,30 @@ class BoilerplateScraper {
|
|
|
16853
17979
|
this.markdownScraper = new MarkdownScraper(tools, options);
|
|
16854
17980
|
}
|
|
16855
17981
|
/**
|
|
16856
|
-
* Convert the
|
|
17982
|
+
* Convert the `.@@` to `.md` file and returns intermediate source
|
|
16857
17983
|
*
|
|
16858
17984
|
* Note: `$` is used to indicate that this function is not a pure function - it leaves files on the disk and you are responsible for cleaning them by calling `destroy` method of returned object
|
|
16859
17985
|
*/
|
|
16860
17986
|
async $convert(source) {
|
|
16861
17987
|
var _a;
|
|
16862
17988
|
const { rootDirname = process.cwd(), cacheDirname = DEFAULT_SCRAPE_CACHE_DIRNAME, intermediateFilesStrategy = DEFAULT_INTERMEDIATE_FILES_STRATEGY, isVerbose = DEFAULT_IS_VERBOSE, } = this.options;
|
|
16863
|
-
// TODO:
|
|
17989
|
+
// TODO: @@ Preserve or delete
|
|
16864
17990
|
if (!$isRunningInNode()) {
|
|
16865
17991
|
throw new KnowledgeScrapeError('BoilerplateScraper is only supported in Node environment');
|
|
16866
17992
|
}
|
|
16867
|
-
// TODO:
|
|
17993
|
+
// TODO: @@ Preserve or delete
|
|
16868
17994
|
if (this.tools.fs === undefined) {
|
|
16869
17995
|
throw new EnvironmentMismatchError('Can not scrape boilerplates without filesystem tools');
|
|
16870
17996
|
// <- TODO: [🧠] What is the best error type here`
|
|
16871
17997
|
}
|
|
16872
|
-
// TODO:
|
|
17998
|
+
// TODO: @@ Preserve, delete or modify
|
|
16873
17999
|
if (((_a = this.tools.executables) === null || _a === void 0 ? void 0 : _a.pandocPath) === undefined) {
|
|
16874
18000
|
throw new MissingToolsError('Pandoc is required for scraping .docx files');
|
|
16875
18001
|
}
|
|
16876
|
-
// TODO:
|
|
18002
|
+
// TODO: @@ Preserve, delete or modify
|
|
16877
18003
|
if (source.filename === null) {
|
|
16878
18004
|
// TODO: [🧠] Maybe save file as temporary
|
|
16879
|
-
throw new KnowledgeScrapeError('When parsing
|
|
18005
|
+
throw new KnowledgeScrapeError('When parsing .@@ file, it must be real file in the file system');
|
|
16880
18006
|
}
|
|
16881
18007
|
const extension = getFileExtension(source.filename);
|
|
16882
18008
|
const cacheFilehandler = await getScraperIntermediateSource(source, {
|
|
@@ -16886,7 +18012,7 @@ class BoilerplateScraper {
|
|
|
16886
18012
|
extension: 'md',
|
|
16887
18013
|
isVerbose,
|
|
16888
18014
|
});
|
|
16889
|
-
// TODO:
|
|
18015
|
+
// TODO: @@ Preserve, delete or modify
|
|
16890
18016
|
// Note: Running Pandoc ONLY if the file in the cache does not exist
|
|
16891
18017
|
if (!(await isFileExisting(cacheFilehandler.filename, this.tools.fs))) {
|
|
16892
18018
|
const command = `"${this.tools.executables.pandocPath}" -f ${extension} -t markdown "${source.filename}" -o "${cacheFilehandler.filename}"`;
|
|
@@ -16912,7 +18038,7 @@ class BoilerplateScraper {
|
|
|
16912
18038
|
*/
|
|
16913
18039
|
async scrape(source) {
|
|
16914
18040
|
const cacheFilehandler = await this.$convert(source);
|
|
16915
|
-
// TODO:
|
|
18041
|
+
// TODO: @@ Preserve, delete or modify
|
|
16916
18042
|
const markdownSource = {
|
|
16917
18043
|
source: source.source,
|
|
16918
18044
|
filename: cacheFilehandler.filename,
|
|
@@ -16943,7 +18069,7 @@ class BoilerplateScraper {
|
|
|
16943
18069
|
* TODO: [👣] Converted documents can act as cached items - there is no need to run conversion each time
|
|
16944
18070
|
* TODO: [🪂] Do it in parallel
|
|
16945
18071
|
* Note: No need to aggregate usage here, it is done by intercepting the llmTools
|
|
16946
|
-
*
|
|
18072
|
+
* @@ Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
|
|
16947
18073
|
*/
|
|
16948
18074
|
|
|
16949
18075
|
/**
|
|
@@ -17277,7 +18403,8 @@ class LegacyDocumentScraper {
|
|
|
17277
18403
|
*/
|
|
17278
18404
|
|
|
17279
18405
|
/**
|
|
17280
|
-
*
|
|
18406
|
+
* Creates a scraper for legacy document formats (.doc, .rtf, etc).
|
|
18407
|
+
* Uses LibreOffice for conversion to extract content from older document formats.
|
|
17281
18408
|
*
|
|
17282
18409
|
* @public exported from `@promptbook/legacy-documents`
|
|
17283
18410
|
*/
|
|
@@ -17304,7 +18431,7 @@ const _LegacyDocumentScraperRegistration = $scrapersRegister.register(createLega
|
|
|
17304
18431
|
*/
|
|
17305
18432
|
|
|
17306
18433
|
/**
|
|
17307
|
-
*
|
|
18434
|
+
* Creates a scraper for document content.
|
|
17308
18435
|
*
|
|
17309
18436
|
* @public exported from `@promptbook/documents`
|
|
17310
18437
|
*/
|
|
@@ -17331,7 +18458,7 @@ const _DocumentScraperRegistration = $scrapersRegister.register(createDocumentSc
|
|
|
17331
18458
|
*/
|
|
17332
18459
|
|
|
17333
18460
|
/**
|
|
17334
|
-
*
|
|
18461
|
+
* Creates a scraper for markdown content.
|
|
17335
18462
|
*
|
|
17336
18463
|
* @public exported from `@promptbook/markdown-utils`
|
|
17337
18464
|
*/
|
|
@@ -17437,8 +18564,8 @@ class MarkitdownScraper {
|
|
|
17437
18564
|
extension: 'md',
|
|
17438
18565
|
isVerbose,
|
|
17439
18566
|
});
|
|
17440
|
-
// TODO:
|
|
17441
|
-
// Note: Running
|
|
18567
|
+
// TODO: Determine if Markitdown conversion should run only if the cache file doesn't exist, or always.
|
|
18568
|
+
// Note: Running Markitdown conversion ONLY if the file in the cache does not exist
|
|
17442
18569
|
if (!(await isFileExisting(cacheFilehandler.filename, this.tools.fs))) {
|
|
17443
18570
|
const src = source.filename || source.url || null;
|
|
17444
18571
|
// console.log('!!', { src, source, cacheFilehandler });
|
|
@@ -17460,11 +18587,11 @@ class MarkitdownScraper {
|
|
|
17460
18587
|
return cacheFilehandler;
|
|
17461
18588
|
}
|
|
17462
18589
|
/**
|
|
17463
|
-
* Scrapes the
|
|
18590
|
+
* Scrapes the source document (PDF, DOCX, etc.) and returns the knowledge pieces or `null` if it can't scrape it.
|
|
17464
18591
|
*/
|
|
17465
18592
|
async scrape(source) {
|
|
17466
18593
|
const cacheFilehandler = await this.$convert(source);
|
|
17467
|
-
// TODO:
|
|
18594
|
+
// TODO: Ensure this correctly creates the source object for the internal MarkdownScraper using the converted file.
|
|
17468
18595
|
const markdownSource = {
|
|
17469
18596
|
source: source.source,
|
|
17470
18597
|
filename: cacheFilehandler.filename,
|
|
@@ -17608,7 +18735,8 @@ class PdfScraper {
|
|
|
17608
18735
|
*/
|
|
17609
18736
|
|
|
17610
18737
|
/**
|
|
17611
|
-
*
|
|
18738
|
+
* Factory function to create an instance of PdfScraper.
|
|
18739
|
+
* It bundles the scraper class with its metadata.
|
|
17612
18740
|
*
|
|
17613
18741
|
* @public exported from `@promptbook/pdf`
|
|
17614
18742
|
*/
|
|
@@ -17784,7 +18912,8 @@ class WebsiteScraper {
|
|
|
17784
18912
|
*/
|
|
17785
18913
|
|
|
17786
18914
|
/**
|
|
17787
|
-
*
|
|
18915
|
+
* Factory function to create an instance of WebsiteScraper.
|
|
18916
|
+
* It bundles the scraper class with its metadata.
|
|
17788
18917
|
*
|
|
17789
18918
|
* @public exported from `@promptbook/website-crawler`
|
|
17790
18919
|
*/
|