@promptbook/utils 0.92.0-8 → 0.92.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -8
- package/esm/index.es.js +864 -827
- 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 +26 -14
- package/esm/typings/src/_packages/types.index.d.ts +6 -2
- 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/parsePipeline.d.ts +2 -2
- package/esm/typings/src/errors/0-BoilerplateError.d.ts +2 -2
- package/esm/typings/src/errors/CollectionError.d.ts +1 -1
- 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/locateApp.d.ts +2 -2
- 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/ExecutionTask.d.ts +19 -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/PromptbookFetch.d.ts +1 -1
- package/esm/typings/src/execution/ScriptExecutionTools.d.ts +1 -1
- package/esm/typings/src/execution/createPipelineExecutor/$OngoingTaskResult.d.ts +12 -9
- package/esm/typings/src/execution/createPipelineExecutor/10-executePipeline.d.ts +13 -10
- package/esm/typings/src/execution/createPipelineExecutor/20-executeTask.d.ts +12 -9
- package/esm/typings/src/execution/createPipelineExecutor/30-executeFormatSubvalues.d.ts +15 -3
- package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempts.d.ts +21 -15
- 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 +12 -9
- package/esm/typings/src/execution/createPipelineExecutor/getReservedParametersForTask.d.ts +18 -5
- package/esm/typings/src/execution/createPipelineExecutor/knowledgePiecesToString.d.ts +9 -0
- package/esm/typings/src/execution/execution-report/ExecutionReportJson.d.ts +1 -1
- package/esm/typings/src/execution/execution-report/ExecutionReportString.d.ts +1 -1
- package/esm/typings/src/execution/translation/automatic-translate/automatic-translators/LindatAutomaticTranslator.d.ts +4 -4
- package/esm/typings/src/execution/utils/checkExpectations.d.ts +3 -3
- package/esm/typings/src/execution/utils/uncertainNumber.d.ts +3 -2
- package/esm/typings/src/execution/utils/usageToWorktime.d.ts +1 -1
- 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/JsonFormatParser.d.ts +19 -0
- package/esm/typings/src/formats/json/utils/isValidJsonString.d.ts +1 -1
- package/esm/typings/src/formats/json/utils/jsonParse.d.ts +0 -3
- 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 +18 -5
- package/esm/typings/src/llm-providers/_common/register/LlmToolsConfiguration.d.ts +11 -4
- package/esm/typings/src/llm-providers/_common/register/LlmToolsMetadata.d.ts +21 -42
- package/esm/typings/src/llm-providers/_common/register/LlmToolsOptions.d.ts +9 -2
- package/esm/typings/src/llm-providers/_common/register/createLlmToolsFromConfiguration.d.ts +13 -4
- 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 +11 -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/AnthropicClaudeExecutionTools.d.ts +6 -0
- 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 +5 -1
- package/esm/typings/src/llm-providers/azure-openai/AzureOpenAiExecutionToolsOptions.d.ts +4 -4
- package/esm/typings/src/llm-providers/deepseek/deepseek-models.d.ts +1 -1
- package/esm/typings/src/llm-providers/google/google-models.d.ts +1 -1
- package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionTools.d.ts +1 -1
- 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/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 +10 -7
- package/esm/typings/src/pipeline/PipelineJson/ParameterJson.d.ts +1 -1
- 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/extractBlock.d.ts +1 -1
- package/esm/typings/src/postprocessing/utils/extractJsonBlock.d.ts +2 -2
- package/esm/typings/src/prepare/prepareTasks.d.ts +8 -5
- package/esm/typings/src/remote-server/openapi.d.ts +1 -1
- package/esm/typings/src/remote-server/socket-types/listModels/PromptbookServer_ListModels_Response.d.ts +1 -1
- package/esm/typings/src/remote-server/startRemoteServer.d.ts +1 -1
- package/esm/typings/src/remote-server/types/RemoteServerOptions.d.ts +7 -6
- 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/prepareKnowledgePieces.d.ts +2 -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/JavascriptExecutionTools.d.ts +1 -1
- package/esm/typings/src/scripting/javascript/postprocessing-functions.d.ts +5 -1
- package/esm/typings/src/scripting/javascript/utils/preserve.d.ts +1 -1
- package/esm/typings/src/storage/_common/PromptbookStorage.d.ts +1 -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 +11 -0
- package/esm/typings/src/storage/local-storage/utils/IndexedDbStorageOptions.d.ts +14 -0
- package/esm/typings/src/storage/local-storage/utils/makePromptbookStorageFromIndexedDb.d.ts +8 -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/ModelRequirements.d.ts +2 -2
- package/esm/typings/src/types/ModelVariant.d.ts +5 -5
- package/esm/typings/src/types/typeAliases.d.ts +22 -19
- 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/editable/utils/stringifyPipelineJson.d.ts +1 -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/extractAllBlocksFromMarkdown.d.ts +2 -2
- package/esm/typings/src/utils/markdown/extractAllListItemsFromMarkdown.d.ts +1 -1
- package/esm/typings/src/utils/markdown/extractOneBlockFromMarkdown.d.ts +2 -2
- 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/TODO_USE.d.ts +1 -1
- package/esm/typings/src/utils/organization/empty_object.d.ts +2 -2
- package/esm/typings/src/utils/organization/just.d.ts +1 -1
- package/esm/typings/src/utils/organization/just_empty_object.d.ts +4 -4
- package/esm/typings/src/utils/organization/keepUnused.d.ts +1 -1
- package/esm/typings/src/utils/parameters/mapAvailableToExpectedParameters.d.ts +7 -7
- package/esm/typings/src/utils/removeQuotes.d.ts +2 -2
- 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/trimCodeBlock.d.ts +1 -1
- package/esm/typings/src/utils/trimEndOfCodeBlock.d.ts +1 -1
- package/esm/typings/src/utils/unwrapResult.d.ts +2 -2
- 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/utils/validators/semanticVersion/isValidPromptbookVersion.d.ts +1 -1
- package/esm/typings/src/utils/validators/semanticVersion/isValidSemanticVersion.d.ts +1 -1
- package/esm/typings/src/utils/validators/url/isHostnameOnPrivateNetwork.d.ts +1 -1
- package/esm/typings/src/utils/validators/url/isUrlOnPrivateNetwork.d.ts +1 -1
- package/esm/typings/src/utils/validators/url/isValidPipelineUrl.d.ts +1 -1
- package/esm/typings/src/utils/validators/url/isValidUrl.d.ts +1 -1
- package/esm/typings/src/version.d.ts +2 -1
- package/esm/typings/src/wizzard/wizzard.d.ts +1 -1
- package/package.json +13 -1
- package/umd/index.umd.js +871 -834
- 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/json/JsonFormatDefinition.d.ts +0 -19
- package/esm/typings/src/formats/xml/XmlFormatDefinition.d.ts +0 -19
- /package/esm/typings/src/llm-providers/{multiple → _multiple}/MultipleLlmExecutionTools.d.ts +0 -0
- /package/esm/typings/src/llm-providers/{multiple → _multiple}/joinLlmExecutionTools.d.ts +0 -0
- /package/esm/typings/src/llm-providers/{multiple → _multiple}/playground/playground.d.ts +0 -0
package/esm/index.es.js
CHANGED
|
@@ -16,7 +16,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
|
|
|
16
16
|
* @generated
|
|
17
17
|
* @see https://github.com/webgptorg/promptbook
|
|
18
18
|
*/
|
|
19
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.92.0
|
|
19
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.92.0';
|
|
20
20
|
/**
|
|
21
21
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
22
22
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -72,7 +72,7 @@ const VALUE_STRINGS = {
|
|
|
72
72
|
const SMALL_NUMBER = 0.001;
|
|
73
73
|
// <- TODO: [🧜♂️]
|
|
74
74
|
/**
|
|
75
|
-
*
|
|
75
|
+
* Default settings for parsing and generating CSV files in Promptbook.
|
|
76
76
|
*
|
|
77
77
|
* @public exported from `@promptbook/core`
|
|
78
78
|
*/
|
|
@@ -87,6 +87,48 @@ Object.freeze({
|
|
|
87
87
|
* TODO: [🧠][🧜♂️] Maybe join remoteServerUrl and path into single value
|
|
88
88
|
*/
|
|
89
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Orders JSON object by keys
|
|
92
|
+
*
|
|
93
|
+
* @returns The same type of object as the input re-ordered
|
|
94
|
+
* @public exported from `@promptbook/utils`
|
|
95
|
+
*/
|
|
96
|
+
function orderJson(options) {
|
|
97
|
+
const { value, order } = options;
|
|
98
|
+
const orderedValue = {
|
|
99
|
+
...(order === undefined ? {} : Object.fromEntries(order.map((key) => [key, undefined]))),
|
|
100
|
+
...value,
|
|
101
|
+
};
|
|
102
|
+
return orderedValue;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Freezes the given object and all its nested objects recursively
|
|
107
|
+
*
|
|
108
|
+
* Note: `$` is used to indicate that this function is not a pure function - it mutates given object
|
|
109
|
+
* Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
|
|
110
|
+
*
|
|
111
|
+
* @returns The same object as the input, but deeply frozen
|
|
112
|
+
* @public exported from `@promptbook/utils`
|
|
113
|
+
*/
|
|
114
|
+
function $deepFreeze(objectValue) {
|
|
115
|
+
if (Array.isArray(objectValue)) {
|
|
116
|
+
return Object.freeze(objectValue.map((item) => $deepFreeze(item)));
|
|
117
|
+
}
|
|
118
|
+
const propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
119
|
+
for (const propertyName of propertyNames) {
|
|
120
|
+
const value = objectValue[propertyName];
|
|
121
|
+
if (value && typeof value === 'object') {
|
|
122
|
+
$deepFreeze(value);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
Object.freeze(objectValue);
|
|
126
|
+
return objectValue;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
130
|
+
*/
|
|
131
|
+
|
|
90
132
|
/**
|
|
91
133
|
* Make error report URL for the given error
|
|
92
134
|
*
|
|
@@ -142,7 +184,7 @@ class UnexpectedError extends Error {
|
|
|
142
184
|
${block(message)}
|
|
143
185
|
|
|
144
186
|
Note: This error should not happen.
|
|
145
|
-
It's
|
|
187
|
+
It's probably a bug in the pipeline collection
|
|
146
188
|
|
|
147
189
|
Please report issue:
|
|
148
190
|
${block(getErrorReportUrl(new Error(message)).href)}
|
|
@@ -156,158 +198,447 @@ class UnexpectedError extends Error {
|
|
|
156
198
|
}
|
|
157
199
|
|
|
158
200
|
/**
|
|
159
|
-
*
|
|
201
|
+
* This error type indicates that somewhere in the code non-Error object was thrown and it was wrapped into the `WrappedError`
|
|
160
202
|
*
|
|
161
|
-
* @
|
|
162
|
-
* @param _isFirstLetterCapital @@@
|
|
163
|
-
* @returns @@@
|
|
164
|
-
* @example 'helloWorld'
|
|
165
|
-
* @example 'iLovePromptbook'
|
|
166
|
-
* @public exported from `@promptbook/utils`
|
|
203
|
+
* @public exported from `@promptbook/core`
|
|
167
204
|
*/
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
normalizedChar = char.toLowerCase();
|
|
181
|
-
}
|
|
182
|
-
else if (/^[0-9]$/.test(char)) {
|
|
183
|
-
charType = 'NUMBER';
|
|
184
|
-
normalizedChar = char;
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
charType = 'OTHER';
|
|
188
|
-
normalizedChar = '';
|
|
189
|
-
}
|
|
190
|
-
if (!lastCharType) {
|
|
191
|
-
if (_isFirstLetterCapital) {
|
|
192
|
-
normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
else if (charType !== lastCharType &&
|
|
196
|
-
!(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
|
|
197
|
-
!(lastCharType === 'NUMBER') &&
|
|
198
|
-
!(charType === 'NUMBER')) {
|
|
199
|
-
normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
|
|
200
|
-
}
|
|
201
|
-
normalizedName += normalizedChar;
|
|
202
|
-
lastCharType = charType;
|
|
205
|
+
class WrappedError extends Error {
|
|
206
|
+
constructor(whatWasThrown) {
|
|
207
|
+
const tag = `[🤮]`;
|
|
208
|
+
console.error(tag, whatWasThrown);
|
|
209
|
+
super(spaceTrim$2(`
|
|
210
|
+
Non-Error object was thrown
|
|
211
|
+
|
|
212
|
+
Note: Look for ${tag} in the console for more details
|
|
213
|
+
Please report issue on ${ADMIN_EMAIL}
|
|
214
|
+
`));
|
|
215
|
+
this.name = 'WrappedError';
|
|
216
|
+
Object.setPrototypeOf(this, WrappedError.prototype);
|
|
203
217
|
}
|
|
204
|
-
return normalizedName;
|
|
205
218
|
}
|
|
206
|
-
/**
|
|
207
|
-
* TODO: [🌺] Use some intermediate util splitWords
|
|
208
|
-
*/
|
|
209
219
|
|
|
210
220
|
/**
|
|
211
|
-
*
|
|
221
|
+
* Helper used in catch blocks to assert that the error is an instance of `Error`
|
|
212
222
|
*
|
|
213
|
-
* @param
|
|
214
|
-
* @returns
|
|
215
|
-
* @
|
|
223
|
+
* @param whatWasThrown Any object that was thrown
|
|
224
|
+
* @returns Nothing if the error is an instance of `Error`
|
|
225
|
+
* @throws `WrappedError` or `UnexpectedError` if the error is not standard
|
|
226
|
+
*
|
|
227
|
+
* @private within the repository
|
|
216
228
|
*/
|
|
217
|
-
function
|
|
218
|
-
//
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
229
|
+
function assertsError(whatWasThrown) {
|
|
230
|
+
// Case 1: Handle error which was rethrown as `WrappedError`
|
|
231
|
+
if (whatWasThrown instanceof WrappedError) {
|
|
232
|
+
const wrappedError = whatWasThrown;
|
|
233
|
+
throw wrappedError;
|
|
234
|
+
}
|
|
235
|
+
// Case 2: Handle unexpected errors
|
|
236
|
+
if (whatWasThrown instanceof UnexpectedError) {
|
|
237
|
+
const unexpectedError = whatWasThrown;
|
|
238
|
+
throw unexpectedError;
|
|
239
|
+
}
|
|
240
|
+
// Case 3: Handle standard errors - keep them up to consumer
|
|
241
|
+
if (whatWasThrown instanceof Error) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
// Case 4: Handle non-standard errors - wrap them into `WrappedError` and throw
|
|
245
|
+
throw new WrappedError(whatWasThrown);
|
|
224
246
|
}
|
|
225
247
|
|
|
226
248
|
/**
|
|
227
|
-
*
|
|
249
|
+
* Checks if the value is [🚉] serializable as JSON
|
|
250
|
+
* If not, throws an UnexpectedError with a rich error message and tracking
|
|
228
251
|
*
|
|
229
|
-
*
|
|
252
|
+
* - Almost all primitives are serializable BUT:
|
|
253
|
+
* - `undefined` is not serializable
|
|
254
|
+
* - `NaN` is not serializable
|
|
255
|
+
* - Objects and arrays are serializable if all their properties are serializable
|
|
256
|
+
* - Functions are not serializable
|
|
257
|
+
* - Circular references are not serializable
|
|
258
|
+
* - `Date` objects are not serializable
|
|
259
|
+
* - `Map` and `Set` objects are not serializable
|
|
260
|
+
* - `RegExp` objects are not serializable
|
|
261
|
+
* - `Error` objects are not serializable
|
|
262
|
+
* - `Symbol` objects are not serializable
|
|
263
|
+
* - And much more...
|
|
264
|
+
*
|
|
265
|
+
* @throws UnexpectedError if the value is not serializable as JSON
|
|
230
266
|
* @public exported from `@promptbook/utils`
|
|
231
267
|
*/
|
|
232
|
-
function
|
|
233
|
-
|
|
234
|
-
|
|
268
|
+
function checkSerializableAsJson(options) {
|
|
269
|
+
const { value, name, message } = options;
|
|
270
|
+
if (value === undefined) {
|
|
271
|
+
throw new UnexpectedError(`${name} is undefined`);
|
|
235
272
|
}
|
|
236
|
-
if (
|
|
237
|
-
return
|
|
273
|
+
else if (value === null) {
|
|
274
|
+
return;
|
|
238
275
|
}
|
|
239
|
-
if (
|
|
240
|
-
|
|
241
|
-
return false;
|
|
276
|
+
else if (typeof value === 'boolean') {
|
|
277
|
+
return;
|
|
242
278
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
if (/^(\/)/i.test(filenameSlashes)) {
|
|
246
|
-
// console.log(filename, 'Absolute Unix path: /hello.txt');
|
|
247
|
-
return true;
|
|
279
|
+
else if (typeof value === 'number' && !isNaN(value)) {
|
|
280
|
+
return;
|
|
248
281
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
// console.log(filename, 'Absolute Windows path: /hello.txt');
|
|
252
|
-
return true;
|
|
282
|
+
else if (typeof value === 'string') {
|
|
283
|
+
return;
|
|
253
284
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
// console.log(filename, 'Relative path: ./hello.txt');
|
|
257
|
-
return true;
|
|
285
|
+
else if (typeof value === 'symbol') {
|
|
286
|
+
throw new UnexpectedError(`${name} is symbol`);
|
|
258
287
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
// console.log(filename, 'Allow paths like foo/hello');
|
|
262
|
-
return true;
|
|
288
|
+
else if (typeof value === 'function') {
|
|
289
|
+
throw new UnexpectedError(`${name} is function`);
|
|
263
290
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
291
|
+
else if (typeof value === 'object' && Array.isArray(value)) {
|
|
292
|
+
for (let i = 0; i < value.length; i++) {
|
|
293
|
+
checkSerializableAsJson({ name: `${name}[${i}]`, value: value[i], message });
|
|
294
|
+
}
|
|
268
295
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
*/
|
|
296
|
+
else if (typeof value === 'object') {
|
|
297
|
+
if (value instanceof Date) {
|
|
298
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
299
|
+
\`${name}\` is Date
|
|
274
300
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
* - `isValidUrl` which tests any URL
|
|
281
|
-
* - `isValidPipelineUrl` *(this one)* which tests just promptbook URL
|
|
282
|
-
*
|
|
283
|
-
* @public exported from `@promptbook/utils`
|
|
284
|
-
*/
|
|
285
|
-
function isValidUrl(url) {
|
|
286
|
-
if (typeof url !== 'string') {
|
|
287
|
-
return false;
|
|
288
|
-
}
|
|
289
|
-
try {
|
|
290
|
-
if (url.startsWith('blob:')) {
|
|
291
|
-
url = url.replace(/^blob:/, '');
|
|
301
|
+
Use \`string_date_iso8601\` instead
|
|
302
|
+
|
|
303
|
+
Additional message for \`${name}\`:
|
|
304
|
+
${block(message || '(nothing)')}
|
|
305
|
+
`));
|
|
292
306
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
return false;
|
|
307
|
+
else if (value instanceof Map) {
|
|
308
|
+
throw new UnexpectedError(`${name} is Map`);
|
|
296
309
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
310
|
+
else if (value instanceof Set) {
|
|
311
|
+
throw new UnexpectedError(`${name} is Set`);
|
|
312
|
+
}
|
|
313
|
+
else if (value instanceof RegExp) {
|
|
314
|
+
throw new UnexpectedError(`${name} is RegExp`);
|
|
315
|
+
}
|
|
316
|
+
else if (value instanceof Error) {
|
|
317
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
318
|
+
\`${name}\` is unserialized Error
|
|
303
319
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
320
|
+
Use function \`serializeError\`
|
|
321
|
+
|
|
322
|
+
Additional message for \`${name}\`:
|
|
323
|
+
${block(message || '(nothing)')}
|
|
324
|
+
|
|
325
|
+
`));
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
for (const [subName, subValue] of Object.entries(value)) {
|
|
329
|
+
if (subValue === undefined) {
|
|
330
|
+
// Note: undefined in object is serializable - it is just omited
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
checkSerializableAsJson({ name: `${name}.${subName}`, value: subValue, message });
|
|
334
|
+
}
|
|
335
|
+
try {
|
|
336
|
+
JSON.stringify(value); // <- TODO: [0]
|
|
337
|
+
}
|
|
338
|
+
catch (error) {
|
|
339
|
+
assertsError(error);
|
|
340
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
341
|
+
\`${name}\` is not serializable
|
|
342
|
+
|
|
343
|
+
${block(error.stack || error.message)}
|
|
344
|
+
|
|
345
|
+
Additional message for \`${name}\`:
|
|
346
|
+
${block(message || '(nothing)')}
|
|
347
|
+
`));
|
|
348
|
+
}
|
|
349
|
+
/*
|
|
350
|
+
TODO: [0] Is there some more elegant way to check circular references?
|
|
351
|
+
const seen = new Set();
|
|
352
|
+
const stack = [{ value }];
|
|
353
|
+
while (stack.length > 0) {
|
|
354
|
+
const { value } = stack.pop()!;
|
|
355
|
+
if (typeof value === 'object' && value !== null) {
|
|
356
|
+
if (seen.has(value)) {
|
|
357
|
+
throw new UnexpectedError(`${name} has circular reference`);
|
|
358
|
+
}
|
|
359
|
+
seen.add(value);
|
|
360
|
+
if (Array.isArray(value)) {
|
|
361
|
+
stack.push(...value.map((value) => ({ value })));
|
|
362
|
+
} else {
|
|
363
|
+
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
*/
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
373
|
+
\`${name}\` is unknown type
|
|
374
|
+
|
|
375
|
+
Additional message for \`${name}\`:
|
|
376
|
+
${block(message || '(nothing)')}
|
|
377
|
+
`));
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
382
|
+
* TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
383
|
+
* Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
384
|
+
*/
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Creates a deep clone of the given object
|
|
388
|
+
*
|
|
389
|
+
* Note: This method only works for objects that are fully serializable to JSON and do not contain functions, Dates, or special types.
|
|
390
|
+
*
|
|
391
|
+
* @param objectValue The object to clone.
|
|
392
|
+
* @returns A deep, writable clone of the input object.
|
|
393
|
+
* @public exported from `@promptbook/utils`
|
|
394
|
+
*/
|
|
395
|
+
function deepClone(objectValue) {
|
|
396
|
+
return JSON.parse(JSON.stringify(objectValue));
|
|
397
|
+
/*
|
|
398
|
+
TODO: [🧠] Is there a better implementation?
|
|
399
|
+
> const propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
400
|
+
> for (const propertyName of propertyNames) {
|
|
401
|
+
> const value = (objectValue as really_any)[propertyName];
|
|
402
|
+
> if (value && typeof value === 'object') {
|
|
403
|
+
> deepClone(value);
|
|
404
|
+
> }
|
|
405
|
+
> }
|
|
406
|
+
> return Object.assign({}, objectValue);
|
|
407
|
+
*/
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
411
|
+
*/
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Utility to export a JSON object from a function
|
|
415
|
+
*
|
|
416
|
+
* 1) Checks if the value is serializable as JSON
|
|
417
|
+
* 2) Makes a deep clone of the object
|
|
418
|
+
* 2) Orders the object properties
|
|
419
|
+
* 2) Deeply freezes the cloned object
|
|
420
|
+
*
|
|
421
|
+
* Note: This function does not mutates the given object
|
|
422
|
+
*
|
|
423
|
+
* @returns The same type of object as the input but read-only and re-ordered
|
|
424
|
+
* @public exported from `@promptbook/utils`
|
|
425
|
+
*/
|
|
426
|
+
function exportJson(options) {
|
|
427
|
+
const { name, value, order, message } = options;
|
|
428
|
+
checkSerializableAsJson({ name, value, message });
|
|
429
|
+
const orderedValue =
|
|
430
|
+
// TODO: Fix error "Type instantiation is excessively deep and possibly infinite."
|
|
431
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
432
|
+
// @ts-ignore
|
|
433
|
+
order === undefined
|
|
434
|
+
? deepClone(value)
|
|
435
|
+
: orderJson({
|
|
436
|
+
value: value,
|
|
437
|
+
// <- Note: checkSerializableAsJson asserts that the value is serializable as JSON
|
|
438
|
+
order: order,
|
|
439
|
+
});
|
|
440
|
+
$deepFreeze(orderedValue);
|
|
441
|
+
return orderedValue;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
445
|
+
*/
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Nonce which is used for replacing things in strings
|
|
449
|
+
*
|
|
450
|
+
* @private within the repository
|
|
451
|
+
*/
|
|
452
|
+
const REPLACING_NONCE = 'ptbkauk42kV2dzao34faw7FudQUHYPtW';
|
|
453
|
+
/**
|
|
454
|
+
* Placeholder value indicating a parameter is missing its value.
|
|
455
|
+
*
|
|
456
|
+
* @private within the repository
|
|
457
|
+
*/
|
|
458
|
+
const RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
|
|
459
|
+
/**
|
|
460
|
+
* Placeholder value indicating a parameter is restricted and cannot be used directly.
|
|
461
|
+
*
|
|
462
|
+
* @private within the repository
|
|
463
|
+
*/
|
|
464
|
+
const RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;
|
|
465
|
+
/**
|
|
466
|
+
* The names of the parameters that are reserved for special purposes
|
|
467
|
+
*
|
|
468
|
+
* @public exported from `@promptbook/core`
|
|
469
|
+
*/
|
|
470
|
+
const RESERVED_PARAMETER_NAMES = exportJson({
|
|
471
|
+
name: 'RESERVED_PARAMETER_NAMES',
|
|
472
|
+
message: `The names of the parameters that are reserved for special purposes`,
|
|
473
|
+
value: [
|
|
474
|
+
'content',
|
|
475
|
+
'context',
|
|
476
|
+
'knowledge',
|
|
477
|
+
'examples',
|
|
478
|
+
'modelName',
|
|
479
|
+
'currentDate',
|
|
480
|
+
// <- TODO: list here all command names
|
|
481
|
+
// <- TODO: Add more like 'date', 'modelName',...
|
|
482
|
+
// <- TODO: Add [emoji] + instructions ACRY when adding new reserved parameter
|
|
483
|
+
],
|
|
484
|
+
});
|
|
485
|
+
/**
|
|
486
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
487
|
+
*/
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Normalizes a given text to camelCase format.
|
|
491
|
+
*
|
|
492
|
+
* @param text The text to be normalized.
|
|
493
|
+
* @param _isFirstLetterCapital Whether the first letter should be capitalized.
|
|
494
|
+
* @returns The camelCase formatted string.
|
|
495
|
+
* @example 'helloWorld'
|
|
496
|
+
* @example 'iLovePromptbook'
|
|
497
|
+
* @public exported from `@promptbook/utils`
|
|
498
|
+
*/
|
|
499
|
+
function normalizeTo_camelCase(text, _isFirstLetterCapital = false) {
|
|
500
|
+
let charType;
|
|
501
|
+
let lastCharType = null;
|
|
502
|
+
let normalizedName = '';
|
|
503
|
+
for (const char of text) {
|
|
504
|
+
let normalizedChar;
|
|
505
|
+
if (/^[a-z]$/.test(char)) {
|
|
506
|
+
charType = 'LOWERCASE';
|
|
507
|
+
normalizedChar = char;
|
|
508
|
+
}
|
|
509
|
+
else if (/^[A-Z]$/.test(char)) {
|
|
510
|
+
charType = 'UPPERCASE';
|
|
511
|
+
normalizedChar = char.toLowerCase();
|
|
512
|
+
}
|
|
513
|
+
else if (/^[0-9]$/.test(char)) {
|
|
514
|
+
charType = 'NUMBER';
|
|
515
|
+
normalizedChar = char;
|
|
516
|
+
}
|
|
517
|
+
else {
|
|
518
|
+
charType = 'OTHER';
|
|
519
|
+
normalizedChar = '';
|
|
520
|
+
}
|
|
521
|
+
if (!lastCharType) {
|
|
522
|
+
if (_isFirstLetterCapital) {
|
|
523
|
+
normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
else if (charType !== lastCharType &&
|
|
527
|
+
!(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
|
|
528
|
+
!(lastCharType === 'NUMBER') &&
|
|
529
|
+
!(charType === 'NUMBER')) {
|
|
530
|
+
normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
|
|
531
|
+
}
|
|
532
|
+
normalizedName += normalizedChar;
|
|
533
|
+
lastCharType = charType;
|
|
534
|
+
}
|
|
535
|
+
return normalizedName;
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* TODO: [🌺] Use some intermediate util splitWords
|
|
539
|
+
*/
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Removes emojis from a string and fix whitespaces
|
|
543
|
+
*
|
|
544
|
+
* @param text with emojis
|
|
545
|
+
* @returns text without emojis
|
|
546
|
+
* @public exported from `@promptbook/utils`
|
|
547
|
+
*/
|
|
548
|
+
function removeEmojis(text) {
|
|
549
|
+
// Replace emojis (and also ZWJ sequence) with hyphens
|
|
550
|
+
text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
|
|
551
|
+
text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
|
|
552
|
+
text = text.replace(/(\p{Extended_Pictographic})(\u{200D}\p{Extended_Pictographic})*/gu, '$1');
|
|
553
|
+
text = text.replace(/\p{Extended_Pictographic}/gu, '');
|
|
554
|
+
return text;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Tests if given string is valid URL.
|
|
559
|
+
*
|
|
560
|
+
* Note: This does not check if the file exists only if the path is valid
|
|
561
|
+
* @public exported from `@promptbook/utils`
|
|
562
|
+
*/
|
|
563
|
+
function isValidFilePath(filename) {
|
|
564
|
+
if (typeof filename !== 'string') {
|
|
565
|
+
return false;
|
|
566
|
+
}
|
|
567
|
+
if (filename.split('\n').length > 1) {
|
|
568
|
+
return false;
|
|
569
|
+
}
|
|
570
|
+
if (filename.split(' ').length >
|
|
571
|
+
5 /* <- TODO: [🧠][🈷] Make some better non-arbitrary way how to distinct filenames from informational texts */) {
|
|
572
|
+
return false;
|
|
573
|
+
}
|
|
574
|
+
const filenameSlashes = filename.split('\\').join('/');
|
|
575
|
+
// Absolute Unix path: /hello.txt
|
|
576
|
+
if (/^(\/)/i.test(filenameSlashes)) {
|
|
577
|
+
// console.log(filename, 'Absolute Unix path: /hello.txt');
|
|
578
|
+
return true;
|
|
579
|
+
}
|
|
580
|
+
// Absolute Windows path: /hello.txt
|
|
581
|
+
if (/^([A-Z]{1,2}:\/?)\//i.test(filenameSlashes)) {
|
|
582
|
+
// console.log(filename, 'Absolute Windows path: /hello.txt');
|
|
583
|
+
return true;
|
|
584
|
+
}
|
|
585
|
+
// Relative path: ./hello.txt
|
|
586
|
+
if (/^(\.\.?\/)+/i.test(filenameSlashes)) {
|
|
587
|
+
// console.log(filename, 'Relative path: ./hello.txt');
|
|
588
|
+
return true;
|
|
589
|
+
}
|
|
590
|
+
// Allow paths like foo/hello
|
|
591
|
+
if (/^[^/]+\/[^/]+/i.test(filenameSlashes)) {
|
|
592
|
+
// console.log(filename, 'Allow paths like foo/hello');
|
|
593
|
+
return true;
|
|
594
|
+
}
|
|
595
|
+
// Allow paths like hello.book
|
|
596
|
+
if (/^[^/]+\.[^/]+$/i.test(filenameSlashes)) {
|
|
597
|
+
// console.log(filename, 'Allow paths like hello.book');
|
|
598
|
+
return true;
|
|
599
|
+
}
|
|
600
|
+
return false;
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* TODO: [🍏] Implement for MacOs
|
|
604
|
+
*/
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Tests if given string is valid URL.
|
|
608
|
+
*
|
|
609
|
+
* Note: Dataurl are considered perfectly valid.
|
|
610
|
+
* Note: There are two similar functions:
|
|
611
|
+
* - `isValidUrl` which tests any URL
|
|
612
|
+
* - `isValidPipelineUrl` *(this one)* which tests just promptbook URL
|
|
613
|
+
*
|
|
614
|
+
* @public exported from `@promptbook/utils`
|
|
615
|
+
*/
|
|
616
|
+
function isValidUrl(url) {
|
|
617
|
+
if (typeof url !== 'string') {
|
|
618
|
+
return false;
|
|
619
|
+
}
|
|
620
|
+
try {
|
|
621
|
+
if (url.startsWith('blob:')) {
|
|
622
|
+
url = url.replace(/^blob:/, '');
|
|
623
|
+
}
|
|
624
|
+
const urlObject = new URL(url /* because fail is handled */);
|
|
625
|
+
if (!['http:', 'https:', 'data:'].includes(urlObject.protocol)) {
|
|
626
|
+
return false;
|
|
627
|
+
}
|
|
628
|
+
return true;
|
|
629
|
+
}
|
|
630
|
+
catch (error) {
|
|
631
|
+
return false;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
const defaultDiacriticsRemovalMap = [
|
|
636
|
+
{
|
|
637
|
+
base: 'A',
|
|
638
|
+
letters: '\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F',
|
|
639
|
+
},
|
|
640
|
+
{ base: 'AA', letters: '\uA732' },
|
|
641
|
+
{ base: 'AE', letters: '\u00C6\u01FC\u01E2' },
|
|
311
642
|
{ base: 'AO', letters: '\uA734' },
|
|
312
643
|
{ base: 'AU', letters: '\uA736' },
|
|
313
644
|
{ base: 'AV', letters: '\uA738\uA73A' },
|
|
@@ -546,10 +877,10 @@ for (let i = 0; i < defaultDiacriticsRemovalMap.length; i++) {
|
|
|
546
877
|
*/
|
|
547
878
|
|
|
548
879
|
/**
|
|
549
|
-
*
|
|
880
|
+
* Removes diacritic marks (accents) from characters in a string.
|
|
550
881
|
*
|
|
551
|
-
* @param input
|
|
552
|
-
* @returns
|
|
882
|
+
* @param input The string containing diacritics to be normalized.
|
|
883
|
+
* @returns The string with diacritics removed or normalized.
|
|
553
884
|
* @public exported from `@promptbook/utils`
|
|
554
885
|
*/
|
|
555
886
|
function removeDiacritics(input) {
|
|
@@ -563,10 +894,10 @@ function removeDiacritics(input) {
|
|
|
563
894
|
*/
|
|
564
895
|
|
|
565
896
|
/**
|
|
566
|
-
*
|
|
897
|
+
* Converts a given text to kebab-case format.
|
|
567
898
|
*
|
|
568
|
-
* @param text
|
|
569
|
-
* @returns
|
|
899
|
+
* @param text The text to be converted.
|
|
900
|
+
* @returns The kebab-case formatted string.
|
|
570
901
|
* @example 'hello-world'
|
|
571
902
|
* @example 'i-love-promptbook'
|
|
572
903
|
* @public exported from `@promptbook/utils`
|
|
@@ -614,11 +945,11 @@ function normalizeToKebabCase(text) {
|
|
|
614
945
|
*/
|
|
615
946
|
|
|
616
947
|
/**
|
|
617
|
-
*
|
|
948
|
+
* Converts a title string into a normalized name.
|
|
618
949
|
*
|
|
619
|
-
* @param value
|
|
620
|
-
* @returns
|
|
621
|
-
* @example
|
|
950
|
+
* @param value The title string to be converted to a name.
|
|
951
|
+
* @returns A normalized name derived from the input title.
|
|
952
|
+
* @example 'Hello World!' -> 'hello-world'
|
|
622
953
|
* @public exported from `@promptbook/utils`
|
|
623
954
|
*/
|
|
624
955
|
function titleToName(value) {
|
|
@@ -646,45 +977,43 @@ function titleToName(value) {
|
|
|
646
977
|
*/
|
|
647
978
|
function renderPromptbookMermaid(pipelineJson, options) {
|
|
648
979
|
const { linkTask = () => null } = options || {};
|
|
980
|
+
const MERMAID_PREFIX = 'pipeline_';
|
|
981
|
+
const MERMAID_KNOWLEDGE_NAME = MERMAID_PREFIX + 'knowledge';
|
|
982
|
+
const MERMAID_RESERVED_NAME = MERMAID_PREFIX + 'reserved';
|
|
983
|
+
const MERMAID_INPUT_NAME = MERMAID_PREFIX + 'input';
|
|
984
|
+
const MERMAID_OUTPUT_NAME = MERMAID_PREFIX + 'output';
|
|
649
985
|
const parameterNameToTaskName = (parameterName) => {
|
|
986
|
+
if (parameterName === 'knowledge') {
|
|
987
|
+
return MERMAID_KNOWLEDGE_NAME;
|
|
988
|
+
}
|
|
989
|
+
else if (RESERVED_PARAMETER_NAMES.includes(parameterName)) {
|
|
990
|
+
return MERMAID_RESERVED_NAME;
|
|
991
|
+
}
|
|
650
992
|
const parameter = pipelineJson.parameters.find((parameter) => parameter.name === parameterName);
|
|
651
993
|
if (!parameter) {
|
|
652
994
|
throw new UnexpectedError(`Could not find {${parameterName}}`);
|
|
653
|
-
// <- TODO:
|
|
995
|
+
// <- TODO: This causes problems when {knowledge} and other reserved parameters are used
|
|
654
996
|
}
|
|
655
997
|
if (parameter.isInput) {
|
|
656
|
-
return
|
|
998
|
+
return MERMAID_INPUT_NAME;
|
|
657
999
|
}
|
|
658
1000
|
const task = pipelineJson.tasks.find((task) => task.resultingParameterName === parameterName);
|
|
659
1001
|
if (!task) {
|
|
660
1002
|
throw new Error(`Could not find task for {${parameterName}}`);
|
|
661
1003
|
}
|
|
662
|
-
return task.name || normalizeTo_camelCase('task-' + titleToName(task.title));
|
|
1004
|
+
return MERMAID_PREFIX + (task.name || normalizeTo_camelCase('task-' + titleToName(task.title)));
|
|
663
1005
|
};
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
%% 🔮 Tip: Open this on GitHub or in the VSCode website to see the Mermaid graph visually
|
|
667
|
-
|
|
668
|
-
flowchart LR
|
|
669
|
-
subgraph "${pipelineJson.title}"
|
|
670
|
-
|
|
671
|
-
direction TB
|
|
672
|
-
|
|
673
|
-
input((Input)):::input
|
|
674
|
-
${block(pipelineJson.tasks
|
|
1006
|
+
const inputAndIntermediateParametersMermaid = pipelineJson.tasks
|
|
675
1007
|
.flatMap(({ title, dependentParameterNames, resultingParameterName }) => [
|
|
676
1008
|
`${parameterNameToTaskName(resultingParameterName)}("${title}")`,
|
|
677
1009
|
...dependentParameterNames.map((dependentParameterName) => `${parameterNameToTaskName(dependentParameterName)}--"{${dependentParameterName}}"-->${parameterNameToTaskName(resultingParameterName)}`),
|
|
678
1010
|
])
|
|
679
|
-
.join('\n')
|
|
680
|
-
|
|
681
|
-
${block(pipelineJson.parameters
|
|
1011
|
+
.join('\n');
|
|
1012
|
+
const outputParametersMermaid = pipelineJson.parameters
|
|
682
1013
|
.filter(({ isOutput }) => isOutput)
|
|
683
|
-
.map(({ name }) => `${parameterNameToTaskName(name)}--"{${name}}"
|
|
684
|
-
.join('\n')
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
${block(pipelineJson.tasks
|
|
1014
|
+
.map(({ name }) => `${parameterNameToTaskName(name)}--"{${name}}"-->${MERMAID_OUTPUT_NAME}`)
|
|
1015
|
+
.join('\n');
|
|
1016
|
+
const linksMermaid = pipelineJson.tasks
|
|
688
1017
|
.map((task) => {
|
|
689
1018
|
const link = linkTask(task);
|
|
690
1019
|
if (link === null) {
|
|
@@ -695,10 +1024,44 @@ function renderPromptbookMermaid(pipelineJson, options) {
|
|
|
695
1024
|
return `click ${taskName} href "${href}" "${title}";`;
|
|
696
1025
|
})
|
|
697
1026
|
.filter((line) => line !== '')
|
|
698
|
-
.join('\n')
|
|
1027
|
+
.join('\n');
|
|
1028
|
+
const interactionPointsMermaid = Object.entries({
|
|
1029
|
+
[MERMAID_INPUT_NAME]: 'Input',
|
|
1030
|
+
[MERMAID_OUTPUT_NAME]: 'Output',
|
|
1031
|
+
[MERMAID_RESERVED_NAME]: 'Other',
|
|
1032
|
+
[MERMAID_KNOWLEDGE_NAME]: 'Knowledge',
|
|
1033
|
+
})
|
|
1034
|
+
.filter(([MERMAID_NAME]) => (inputAndIntermediateParametersMermaid + outputParametersMermaid).includes(MERMAID_NAME))
|
|
1035
|
+
.map(([MERMAID_NAME, title]) => `${MERMAID_NAME}((${title})):::${MERMAID_NAME}`)
|
|
1036
|
+
.join('\n');
|
|
1037
|
+
const promptbookMermaid = spaceTrim$2((block) => `
|
|
1038
|
+
|
|
1039
|
+
%% 🔮 Tip: Open this on GitHub or in the VSCode website to see the Mermaid graph visually
|
|
1040
|
+
|
|
1041
|
+
flowchart LR
|
|
1042
|
+
subgraph "${pipelineJson.title}"
|
|
1043
|
+
|
|
1044
|
+
%% Basic configuration
|
|
1045
|
+
direction TB
|
|
1046
|
+
|
|
1047
|
+
%% Interaction points from pipeline to outside
|
|
1048
|
+
${block(interactionPointsMermaid)}
|
|
1049
|
+
|
|
1050
|
+
%% Input and intermediate parameters
|
|
1051
|
+
${block(inputAndIntermediateParametersMermaid)}
|
|
699
1052
|
|
|
700
|
-
|
|
701
|
-
|
|
1053
|
+
|
|
1054
|
+
%% Output parameters
|
|
1055
|
+
${block(outputParametersMermaid)}
|
|
1056
|
+
|
|
1057
|
+
%% Links
|
|
1058
|
+
${block(linksMermaid)}
|
|
1059
|
+
|
|
1060
|
+
%% Styles
|
|
1061
|
+
classDef ${MERMAID_INPUT_NAME} color: grey;
|
|
1062
|
+
classDef ${MERMAID_OUTPUT_NAME} color: grey;
|
|
1063
|
+
classDef ${MERMAID_RESERVED_NAME} color: grey;
|
|
1064
|
+
classDef ${MERMAID_KNOWLEDGE_NAME} color: grey;
|
|
702
1065
|
|
|
703
1066
|
end;
|
|
704
1067
|
|
|
@@ -757,7 +1120,7 @@ class AuthenticationError extends Error {
|
|
|
757
1120
|
}
|
|
758
1121
|
|
|
759
1122
|
/**
|
|
760
|
-
* This error indicates that the pipeline collection cannot be
|
|
1123
|
+
* This error indicates that the pipeline collection cannot be properly loaded
|
|
761
1124
|
*
|
|
762
1125
|
* @public exported from `@promptbook/core`
|
|
763
1126
|
*/
|
|
@@ -778,774 +1141,444 @@ class EnvironmentMismatchError extends Error {
|
|
|
778
1141
|
constructor(message) {
|
|
779
1142
|
super(message);
|
|
780
1143
|
this.name = 'EnvironmentMismatchError';
|
|
781
|
-
Object.setPrototypeOf(this, EnvironmentMismatchError.prototype);
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
/**
|
|
786
|
-
* This error occurs when some expectation is not met in the execution of the pipeline
|
|
787
|
-
*
|
|
788
|
-
* @public exported from `@promptbook/core`
|
|
789
|
-
* Note: Do not throw this error, its reserved for `checkExpectations` and `createPipelineExecutor` and public ONLY to be serializable through remote server
|
|
790
|
-
* Note: Always thrown in `checkExpectations` and catched in `createPipelineExecutor` and rethrown as `PipelineExecutionError`
|
|
791
|
-
* Note: This is a kindof subtype of PipelineExecutionError
|
|
792
|
-
*/
|
|
793
|
-
class ExpectError extends Error {
|
|
794
|
-
constructor(message) {
|
|
795
|
-
super(message);
|
|
796
|
-
this.name = 'ExpectError';
|
|
797
|
-
Object.setPrototypeOf(this, ExpectError.prototype);
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
/**
|
|
802
|
-
* This error indicates that the promptbook can not retrieve knowledge from external sources
|
|
803
|
-
*
|
|
804
|
-
* @public exported from `@promptbook/core`
|
|
805
|
-
*/
|
|
806
|
-
class KnowledgeScrapeError extends Error {
|
|
807
|
-
constructor(message) {
|
|
808
|
-
super(message);
|
|
809
|
-
this.name = 'KnowledgeScrapeError';
|
|
810
|
-
Object.setPrototypeOf(this, KnowledgeScrapeError.prototype);
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
/**
|
|
815
|
-
* This error type indicates that some limit was reached
|
|
816
|
-
*
|
|
817
|
-
* @public exported from `@promptbook/core`
|
|
818
|
-
*/
|
|
819
|
-
class LimitReachedError extends Error {
|
|
820
|
-
constructor(message) {
|
|
821
|
-
super(message);
|
|
822
|
-
this.name = 'LimitReachedError';
|
|
823
|
-
Object.setPrototypeOf(this, LimitReachedError.prototype);
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
/**
|
|
828
|
-
* This error type indicates that some tools are missing for pipeline execution or preparation
|
|
829
|
-
*
|
|
830
|
-
* @public exported from `@promptbook/core`
|
|
831
|
-
*/
|
|
832
|
-
class MissingToolsError extends Error {
|
|
833
|
-
constructor(message) {
|
|
834
|
-
super(spaceTrim$2((block) => `
|
|
835
|
-
${block(message)}
|
|
836
|
-
|
|
837
|
-
Note: You have probbably forgot to provide some tools for pipeline execution or preparation
|
|
838
|
-
|
|
839
|
-
`));
|
|
840
|
-
this.name = 'MissingToolsError';
|
|
841
|
-
Object.setPrototypeOf(this, MissingToolsError.prototype);
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
/**
|
|
846
|
-
* This error indicates that promptbook not found in the collection
|
|
847
|
-
*
|
|
848
|
-
* @public exported from `@promptbook/core`
|
|
849
|
-
*/
|
|
850
|
-
class NotFoundError extends Error {
|
|
851
|
-
constructor(message) {
|
|
852
|
-
super(message);
|
|
853
|
-
this.name = 'NotFoundError';
|
|
854
|
-
Object.setPrototypeOf(this, NotFoundError.prototype);
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
/**
|
|
859
|
-
* This error type indicates that some part of the code is not implemented yet
|
|
860
|
-
*
|
|
861
|
-
* @public exported from `@promptbook/core`
|
|
862
|
-
*/
|
|
863
|
-
class NotYetImplementedError extends Error {
|
|
864
|
-
constructor(message) {
|
|
865
|
-
super(spaceTrim$2((block) => `
|
|
866
|
-
${block(message)}
|
|
867
|
-
|
|
868
|
-
Note: This feature is not implemented yet but it will be soon.
|
|
869
|
-
|
|
870
|
-
If you want speed up the implementation or just read more, look here:
|
|
871
|
-
https://github.com/webgptorg/promptbook
|
|
872
|
-
|
|
873
|
-
Or contact us on pavol@ptbk.io
|
|
874
|
-
|
|
875
|
-
`));
|
|
876
|
-
this.name = 'NotYetImplementedError';
|
|
877
|
-
Object.setPrototypeOf(this, NotYetImplementedError.prototype);
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
/**
|
|
882
|
-
* This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
|
|
883
|
-
*
|
|
884
|
-
* @public exported from `@promptbook/core`
|
|
885
|
-
*/
|
|
886
|
-
class ParseError extends Error {
|
|
887
|
-
constructor(message) {
|
|
888
|
-
super(message);
|
|
889
|
-
this.name = 'ParseError';
|
|
890
|
-
Object.setPrototypeOf(this, ParseError.prototype);
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
/**
|
|
894
|
-
* TODO: Maybe split `ParseError` and `ApplyError`
|
|
895
|
-
*/
|
|
896
|
-
|
|
897
|
-
/**
|
|
898
|
-
* Generates random token
|
|
899
|
-
*
|
|
900
|
-
* Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
|
|
901
|
-
*
|
|
902
|
-
* @private internal helper function
|
|
903
|
-
* @returns secure random token
|
|
904
|
-
*/
|
|
905
|
-
function $randomToken(randomness) {
|
|
906
|
-
return randomBytes(randomness).toString('hex');
|
|
907
|
-
}
|
|
908
|
-
/**
|
|
909
|
-
* TODO: Maybe use nanoid instead https://github.com/ai/nanoid
|
|
910
|
-
*/
|
|
911
|
-
|
|
912
|
-
/**
|
|
913
|
-
* This error indicates errors during the execution of the pipeline
|
|
914
|
-
*
|
|
915
|
-
* @public exported from `@promptbook/core`
|
|
916
|
-
*/
|
|
917
|
-
class PipelineExecutionError extends Error {
|
|
918
|
-
constructor(message) {
|
|
919
|
-
// Added id parameter
|
|
920
|
-
super(message);
|
|
921
|
-
this.name = 'PipelineExecutionError';
|
|
922
|
-
// TODO: [🐙] DRY - Maybe $randomId
|
|
923
|
-
this.id = `error-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid simmilar char conflicts */)}`;
|
|
924
|
-
Object.setPrototypeOf(this, PipelineExecutionError.prototype);
|
|
1144
|
+
Object.setPrototypeOf(this, EnvironmentMismatchError.prototype);
|
|
925
1145
|
}
|
|
926
1146
|
}
|
|
927
|
-
/**
|
|
928
|
-
* TODO: [🧠][🌂] Add id to all errors
|
|
929
|
-
*/
|
|
930
1147
|
|
|
931
1148
|
/**
|
|
932
|
-
* This error
|
|
1149
|
+
* This error occurs when some expectation is not met in the execution of the pipeline
|
|
933
1150
|
*
|
|
934
1151
|
* @public exported from `@promptbook/core`
|
|
1152
|
+
* Note: Do not throw this error, its reserved for `checkExpectations` and `createPipelineExecutor` and public ONLY to be serializable through remote server
|
|
1153
|
+
* Note: Always thrown in `checkExpectations` and catched in `createPipelineExecutor` and rethrown as `PipelineExecutionError`
|
|
1154
|
+
* Note: This is a kindof subtype of PipelineExecutionError
|
|
935
1155
|
*/
|
|
936
|
-
class
|
|
1156
|
+
class ExpectError extends Error {
|
|
937
1157
|
constructor(message) {
|
|
938
1158
|
super(message);
|
|
939
|
-
this.name = '
|
|
940
|
-
Object.setPrototypeOf(this,
|
|
1159
|
+
this.name = 'ExpectError';
|
|
1160
|
+
Object.setPrototypeOf(this, ExpectError.prototype);
|
|
941
1161
|
}
|
|
942
1162
|
}
|
|
943
1163
|
|
|
944
1164
|
/**
|
|
945
|
-
* This error indicates
|
|
1165
|
+
* This error indicates that the promptbook can not retrieve knowledge from external sources
|
|
946
1166
|
*
|
|
947
1167
|
* @public exported from `@promptbook/core`
|
|
948
1168
|
*/
|
|
949
|
-
class
|
|
1169
|
+
class KnowledgeScrapeError extends Error {
|
|
950
1170
|
constructor(message) {
|
|
951
1171
|
super(message);
|
|
952
|
-
this.name = '
|
|
953
|
-
Object.setPrototypeOf(this,
|
|
1172
|
+
this.name = 'KnowledgeScrapeError';
|
|
1173
|
+
Object.setPrototypeOf(this, KnowledgeScrapeError.prototype);
|
|
954
1174
|
}
|
|
955
1175
|
}
|
|
956
1176
|
|
|
957
1177
|
/**
|
|
958
|
-
*
|
|
1178
|
+
* This error type indicates that some limit was reached
|
|
959
1179
|
*
|
|
960
1180
|
* @public exported from `@promptbook/core`
|
|
961
1181
|
*/
|
|
962
|
-
class
|
|
1182
|
+
class LimitReachedError extends Error {
|
|
963
1183
|
constructor(message) {
|
|
964
1184
|
super(message);
|
|
965
|
-
this.name = '
|
|
966
|
-
Object.setPrototypeOf(this,
|
|
1185
|
+
this.name = 'LimitReachedError';
|
|
1186
|
+
Object.setPrototypeOf(this, LimitReachedError.prototype);
|
|
967
1187
|
}
|
|
968
1188
|
}
|
|
969
1189
|
|
|
970
1190
|
/**
|
|
971
|
-
* This error type indicates that
|
|
1191
|
+
* This error type indicates that some tools are missing for pipeline execution or preparation
|
|
972
1192
|
*
|
|
973
1193
|
* @public exported from `@promptbook/core`
|
|
974
1194
|
*/
|
|
975
|
-
class
|
|
976
|
-
constructor(
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
super(spaceTrim$2(`
|
|
980
|
-
Non-Error object was thrown
|
|
1195
|
+
class MissingToolsError extends Error {
|
|
1196
|
+
constructor(message) {
|
|
1197
|
+
super(spaceTrim$2((block) => `
|
|
1198
|
+
${block(message)}
|
|
981
1199
|
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
this.name = '
|
|
986
|
-
Object.setPrototypeOf(this,
|
|
1200
|
+
Note: You have probably forgot to provide some tools for pipeline execution or preparation
|
|
1201
|
+
|
|
1202
|
+
`));
|
|
1203
|
+
this.name = 'MissingToolsError';
|
|
1204
|
+
Object.setPrototypeOf(this, MissingToolsError.prototype);
|
|
987
1205
|
}
|
|
988
1206
|
}
|
|
989
1207
|
|
|
990
1208
|
/**
|
|
991
|
-
*
|
|
1209
|
+
* This error indicates that promptbook not found in the collection
|
|
992
1210
|
*
|
|
993
1211
|
* @public exported from `@promptbook/core`
|
|
994
1212
|
*/
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
ExpectError,
|
|
1001
|
-
KnowledgeScrapeError,
|
|
1002
|
-
LimitReachedError,
|
|
1003
|
-
MissingToolsError,
|
|
1004
|
-
NotFoundError,
|
|
1005
|
-
NotYetImplementedError,
|
|
1006
|
-
ParseError,
|
|
1007
|
-
PipelineExecutionError,
|
|
1008
|
-
PipelineLogicError,
|
|
1009
|
-
PipelineUrlError,
|
|
1010
|
-
AuthenticationError,
|
|
1011
|
-
PromptbookFetchError,
|
|
1012
|
-
UnexpectedError,
|
|
1013
|
-
WrappedError,
|
|
1014
|
-
// TODO: [🪑]> VersionMismatchError,
|
|
1015
|
-
};
|
|
1016
|
-
/**
|
|
1017
|
-
* Index of all javascript errors
|
|
1018
|
-
*
|
|
1019
|
-
* @private for internal usage
|
|
1020
|
-
*/
|
|
1021
|
-
const COMMON_JAVASCRIPT_ERRORS = {
|
|
1022
|
-
Error,
|
|
1023
|
-
EvalError,
|
|
1024
|
-
RangeError,
|
|
1025
|
-
ReferenceError,
|
|
1026
|
-
SyntaxError,
|
|
1027
|
-
TypeError,
|
|
1028
|
-
URIError,
|
|
1029
|
-
AggregateError,
|
|
1030
|
-
/*
|
|
1031
|
-
Note: Not widely supported
|
|
1032
|
-
> InternalError,
|
|
1033
|
-
> ModuleError,
|
|
1034
|
-
> HeapError,
|
|
1035
|
-
> WebAssemblyCompileError,
|
|
1036
|
-
> WebAssemblyRuntimeError,
|
|
1037
|
-
*/
|
|
1038
|
-
};
|
|
1039
|
-
/**
|
|
1040
|
-
* Index of all errors
|
|
1041
|
-
*
|
|
1042
|
-
* @private for internal usage
|
|
1043
|
-
*/
|
|
1044
|
-
const ALL_ERRORS = {
|
|
1045
|
-
...PROMPTBOOK_ERRORS,
|
|
1046
|
-
...COMMON_JAVASCRIPT_ERRORS,
|
|
1047
|
-
};
|
|
1048
|
-
/**
|
|
1049
|
-
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
1050
|
-
*/
|
|
1051
|
-
|
|
1052
|
-
/**
|
|
1053
|
-
* Deserializes the error object
|
|
1054
|
-
*
|
|
1055
|
-
* @public exported from `@promptbook/utils`
|
|
1056
|
-
*/
|
|
1057
|
-
function deserializeError(error) {
|
|
1058
|
-
const { name, stack, id } = error; // Added id
|
|
1059
|
-
let { message } = error;
|
|
1060
|
-
let ErrorClass = ALL_ERRORS[error.name];
|
|
1061
|
-
if (ErrorClass === undefined) {
|
|
1062
|
-
ErrorClass = Error;
|
|
1063
|
-
message = `${name}: ${message}`;
|
|
1064
|
-
}
|
|
1065
|
-
if (stack !== undefined && stack !== '') {
|
|
1066
|
-
message = spaceTrim$1((block) => `
|
|
1067
|
-
${block(message)}
|
|
1068
|
-
|
|
1069
|
-
Original stack trace:
|
|
1070
|
-
${block(stack || '')}
|
|
1071
|
-
`);
|
|
1213
|
+
class NotFoundError extends Error {
|
|
1214
|
+
constructor(message) {
|
|
1215
|
+
super(message);
|
|
1216
|
+
this.name = 'NotFoundError';
|
|
1217
|
+
Object.setPrototypeOf(this, NotFoundError.prototype);
|
|
1072
1218
|
}
|
|
1073
|
-
const deserializedError = new ErrorClass(message);
|
|
1074
|
-
deserializedError.id = id; // Assign id to the error object
|
|
1075
|
-
return deserializedError;
|
|
1076
1219
|
}
|
|
1077
1220
|
|
|
1078
1221
|
/**
|
|
1079
|
-
*
|
|
1222
|
+
* This error type indicates that some part of the code is not implemented yet
|
|
1080
1223
|
*
|
|
1081
|
-
* @public exported from `@promptbook/
|
|
1224
|
+
* @public exported from `@promptbook/core`
|
|
1082
1225
|
*/
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
console.error(spaceTrim$1((block) => `
|
|
1088
|
-
|
|
1089
|
-
Cannot serialize error with name "${name}"
|
|
1226
|
+
class NotYetImplementedError extends Error {
|
|
1227
|
+
constructor(message) {
|
|
1228
|
+
super(spaceTrim$2((block) => `
|
|
1229
|
+
${block(message)}
|
|
1090
1230
|
|
|
1091
|
-
|
|
1092
|
-
https://github.com/webgptorg/promptbook/blob/main/src/errors/0-index.ts
|
|
1231
|
+
Note: This feature is not implemented yet but it will be soon.
|
|
1093
1232
|
|
|
1233
|
+
If you want speed up the implementation or just read more, look here:
|
|
1234
|
+
https://github.com/webgptorg/promptbook
|
|
1094
1235
|
|
|
1095
|
-
|
|
1236
|
+
Or contact us on pavol@ptbk.io
|
|
1096
1237
|
|
|
1097
1238
|
`));
|
|
1239
|
+
this.name = 'NotYetImplementedError';
|
|
1240
|
+
Object.setPrototypeOf(this, NotYetImplementedError.prototype);
|
|
1098
1241
|
}
|
|
1099
|
-
return {
|
|
1100
|
-
name: name,
|
|
1101
|
-
message,
|
|
1102
|
-
stack,
|
|
1103
|
-
id, // Include id in the serialized object
|
|
1104
|
-
};
|
|
1105
1242
|
}
|
|
1106
1243
|
|
|
1107
1244
|
/**
|
|
1108
|
-
*
|
|
1245
|
+
* This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
|
|
1109
1246
|
*
|
|
1110
|
-
* @
|
|
1111
|
-
* @param options - Options for the function
|
|
1112
|
-
* @param callbackfunction - Function to call for each item
|
|
1113
|
-
* @public exported from `@promptbook/utils`
|
|
1114
|
-
* @deprecated [🪂] Use queues instead
|
|
1247
|
+
* @public exported from `@promptbook/core`
|
|
1115
1248
|
*/
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
for (const item of array) {
|
|
1122
|
-
const currentIndex = index++;
|
|
1123
|
-
const task = callbackfunction(item, currentIndex, array);
|
|
1124
|
-
tasks.push(task);
|
|
1125
|
-
runningTasks.push(task);
|
|
1126
|
-
/* not await */ Promise.resolve(task).then(() => {
|
|
1127
|
-
runningTasks = runningTasks.filter((t) => t !== task);
|
|
1128
|
-
});
|
|
1129
|
-
if (maxParallelCount < runningTasks.length) {
|
|
1130
|
-
await Promise.race(runningTasks);
|
|
1131
|
-
}
|
|
1249
|
+
class ParseError extends Error {
|
|
1250
|
+
constructor(message) {
|
|
1251
|
+
super(message);
|
|
1252
|
+
this.name = 'ParseError';
|
|
1253
|
+
Object.setPrototypeOf(this, ParseError.prototype);
|
|
1132
1254
|
}
|
|
1133
|
-
await Promise.all(tasks);
|
|
1134
1255
|
}
|
|
1256
|
+
/**
|
|
1257
|
+
* TODO: Maybe split `ParseError` and `ApplyError`
|
|
1258
|
+
*/
|
|
1135
1259
|
|
|
1136
1260
|
/**
|
|
1137
|
-
*
|
|
1261
|
+
* Generates random token
|
|
1138
1262
|
*
|
|
1139
|
-
*
|
|
1140
|
-
* @returns Nothing if the error is an instance of `Error`
|
|
1141
|
-
* @throws `WrappedError` or `UnexpectedError` if the error is not standard
|
|
1263
|
+
* Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
|
|
1142
1264
|
*
|
|
1143
|
-
* @private
|
|
1265
|
+
* @private internal helper function
|
|
1266
|
+
* @returns secure random token
|
|
1144
1267
|
*/
|
|
1145
|
-
function
|
|
1146
|
-
|
|
1147
|
-
if (whatWasThrown instanceof WrappedError) {
|
|
1148
|
-
const wrappedError = whatWasThrown;
|
|
1149
|
-
throw wrappedError;
|
|
1150
|
-
}
|
|
1151
|
-
// Case 2: Handle unexpected errors
|
|
1152
|
-
if (whatWasThrown instanceof UnexpectedError) {
|
|
1153
|
-
const unexpectedError = whatWasThrown;
|
|
1154
|
-
throw unexpectedError;
|
|
1155
|
-
}
|
|
1156
|
-
// Case 3: Handle standard errors - keep them up to consumer
|
|
1157
|
-
if (whatWasThrown instanceof Error) {
|
|
1158
|
-
return;
|
|
1159
|
-
}
|
|
1160
|
-
// Case 4: Handle non-standard errors - wrap them into `WrappedError` and throw
|
|
1161
|
-
throw new WrappedError(whatWasThrown);
|
|
1268
|
+
function $randomToken(randomness) {
|
|
1269
|
+
return randomBytes(randomness).toString('hex');
|
|
1162
1270
|
}
|
|
1271
|
+
/**
|
|
1272
|
+
* TODO: Maybe use nanoid instead https://github.com/ai/nanoid
|
|
1273
|
+
*/
|
|
1163
1274
|
|
|
1164
1275
|
/**
|
|
1165
|
-
*
|
|
1166
|
-
*
|
|
1167
|
-
* @param value The string to check
|
|
1168
|
-
* @returns True if the string is a valid CSV string, false otherwise
|
|
1276
|
+
* This error indicates errors during the execution of the pipeline
|
|
1169
1277
|
*
|
|
1170
|
-
* @public exported from `@promptbook/
|
|
1278
|
+
* @public exported from `@promptbook/core`
|
|
1171
1279
|
*/
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
//
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
catch (error) {
|
|
1181
|
-
assertsError(error);
|
|
1182
|
-
return false;
|
|
1280
|
+
class PipelineExecutionError extends Error {
|
|
1281
|
+
constructor(message) {
|
|
1282
|
+
// Added id parameter
|
|
1283
|
+
super(message);
|
|
1284
|
+
this.name = 'PipelineExecutionError';
|
|
1285
|
+
// TODO: [🐙] DRY - Maybe $randomId
|
|
1286
|
+
this.id = `error-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid similar char conflicts */)}`;
|
|
1287
|
+
Object.setPrototypeOf(this, PipelineExecutionError.prototype);
|
|
1183
1288
|
}
|
|
1184
1289
|
}
|
|
1290
|
+
/**
|
|
1291
|
+
* TODO: [🧠][🌂] Add id to all errors
|
|
1292
|
+
*/
|
|
1185
1293
|
|
|
1186
1294
|
/**
|
|
1187
|
-
*
|
|
1188
|
-
*
|
|
1189
|
-
* @param value The string to check
|
|
1190
|
-
* @returns True if the string is a valid JSON string, false otherwise
|
|
1295
|
+
* This error indicates that the promptbook object has valid syntax (=can be parsed) but contains logical errors (like circular dependencies)
|
|
1191
1296
|
*
|
|
1192
|
-
* @public exported from `@promptbook/
|
|
1297
|
+
* @public exported from `@promptbook/core`
|
|
1193
1298
|
*/
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
catch (error) {
|
|
1200
|
-
assertsError(error);
|
|
1201
|
-
if (error.message.includes('Unexpected token')) {
|
|
1202
|
-
return false;
|
|
1203
|
-
}
|
|
1204
|
-
return false;
|
|
1299
|
+
class PipelineLogicError extends Error {
|
|
1300
|
+
constructor(message) {
|
|
1301
|
+
super(message);
|
|
1302
|
+
this.name = 'PipelineLogicError';
|
|
1303
|
+
Object.setPrototypeOf(this, PipelineLogicError.prototype);
|
|
1205
1304
|
}
|
|
1206
1305
|
}
|
|
1207
1306
|
|
|
1208
1307
|
/**
|
|
1209
|
-
*
|
|
1210
|
-
*
|
|
1211
|
-
* Note: This is wrapper around `JSON.parse()` with better error and type handling
|
|
1308
|
+
* This error indicates errors in referencing promptbooks between each other
|
|
1212
1309
|
*
|
|
1213
|
-
* @public exported from `@promptbook/
|
|
1310
|
+
* @public exported from `@promptbook/core`
|
|
1214
1311
|
*/
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
console.error('Can not parse JSON from non-string value.', { text: value });
|
|
1221
|
-
throw new Error(spaceTrim$1(`
|
|
1222
|
-
Can not parse JSON from non-string value.
|
|
1223
|
-
|
|
1224
|
-
The value type: ${typeof value}
|
|
1225
|
-
See more in console.
|
|
1226
|
-
`));
|
|
1227
|
-
}
|
|
1228
|
-
try {
|
|
1229
|
-
return JSON.parse(value);
|
|
1230
|
-
}
|
|
1231
|
-
catch (error) {
|
|
1232
|
-
if (!(error instanceof Error)) {
|
|
1233
|
-
throw error;
|
|
1234
|
-
}
|
|
1235
|
-
throw new Error(spaceTrim$1((block) => `
|
|
1236
|
-
${block(error.message)}
|
|
1237
|
-
|
|
1238
|
-
The JSON text:
|
|
1239
|
-
${block(value)}
|
|
1240
|
-
`));
|
|
1312
|
+
class PipelineUrlError extends Error {
|
|
1313
|
+
constructor(message) {
|
|
1314
|
+
super(message);
|
|
1315
|
+
this.name = 'PipelineUrlError';
|
|
1316
|
+
Object.setPrototypeOf(this, PipelineUrlError.prototype);
|
|
1241
1317
|
}
|
|
1242
1318
|
}
|
|
1243
|
-
/**
|
|
1244
|
-
* TODO: !!!! Use in Promptbook.studio
|
|
1245
|
-
*/
|
|
1246
1319
|
|
|
1247
1320
|
/**
|
|
1248
|
-
*
|
|
1249
|
-
*
|
|
1250
|
-
* @param value
|
|
1251
|
-
* @returns True if the string is a valid XML string, false otherwise
|
|
1321
|
+
* Error thrown when a fetch request fails
|
|
1252
1322
|
*
|
|
1253
|
-
* @public exported from `@promptbook/
|
|
1323
|
+
* @public exported from `@promptbook/core`
|
|
1254
1324
|
*/
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
if (parserError.length > 0) {
|
|
1261
|
-
return false;
|
|
1262
|
-
}
|
|
1263
|
-
return true;
|
|
1264
|
-
}
|
|
1265
|
-
catch (error) {
|
|
1266
|
-
assertsError(error);
|
|
1267
|
-
return false;
|
|
1325
|
+
class PromptbookFetchError extends Error {
|
|
1326
|
+
constructor(message) {
|
|
1327
|
+
super(message);
|
|
1328
|
+
this.name = 'PromptbookFetchError';
|
|
1329
|
+
Object.setPrototypeOf(this, PromptbookFetchError.prototype);
|
|
1268
1330
|
}
|
|
1269
1331
|
}
|
|
1270
1332
|
|
|
1271
1333
|
/**
|
|
1272
|
-
*
|
|
1334
|
+
* Index of all custom errors
|
|
1273
1335
|
*
|
|
1274
|
-
* @
|
|
1275
|
-
* @public exported from `@promptbook/utils`
|
|
1336
|
+
* @public exported from `@promptbook/core`
|
|
1276
1337
|
*/
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1338
|
+
const PROMPTBOOK_ERRORS = {
|
|
1339
|
+
AbstractFormatError,
|
|
1340
|
+
CsvFormatError,
|
|
1341
|
+
CollectionError,
|
|
1342
|
+
EnvironmentMismatchError,
|
|
1343
|
+
ExpectError,
|
|
1344
|
+
KnowledgeScrapeError,
|
|
1345
|
+
LimitReachedError,
|
|
1346
|
+
MissingToolsError,
|
|
1347
|
+
NotFoundError,
|
|
1348
|
+
NotYetImplementedError,
|
|
1349
|
+
ParseError,
|
|
1350
|
+
PipelineExecutionError,
|
|
1351
|
+
PipelineLogicError,
|
|
1352
|
+
PipelineUrlError,
|
|
1353
|
+
AuthenticationError,
|
|
1354
|
+
PromptbookFetchError,
|
|
1355
|
+
UnexpectedError,
|
|
1356
|
+
WrappedError,
|
|
1357
|
+
// TODO: [🪑]> VersionMismatchError,
|
|
1358
|
+
};
|
|
1286
1359
|
/**
|
|
1287
|
-
*
|
|
1360
|
+
* Index of all javascript errors
|
|
1288
1361
|
*
|
|
1289
|
-
*
|
|
1290
|
-
|
|
1362
|
+
* @private for internal usage
|
|
1363
|
+
*/
|
|
1364
|
+
const COMMON_JAVASCRIPT_ERRORS = {
|
|
1365
|
+
Error,
|
|
1366
|
+
EvalError,
|
|
1367
|
+
RangeError,
|
|
1368
|
+
ReferenceError,
|
|
1369
|
+
SyntaxError,
|
|
1370
|
+
TypeError,
|
|
1371
|
+
URIError,
|
|
1372
|
+
AggregateError,
|
|
1373
|
+
/*
|
|
1374
|
+
Note: Not widely supported
|
|
1375
|
+
> InternalError,
|
|
1376
|
+
> ModuleError,
|
|
1377
|
+
> HeapError,
|
|
1378
|
+
> WebAssemblyCompileError,
|
|
1379
|
+
> WebAssemblyRuntimeError,
|
|
1380
|
+
*/
|
|
1381
|
+
};
|
|
1382
|
+
/**
|
|
1383
|
+
* Index of all errors
|
|
1291
1384
|
*
|
|
1292
|
-
* @
|
|
1293
|
-
* @public exported from `@promptbook/utils`
|
|
1385
|
+
* @private for internal usage
|
|
1294
1386
|
*/
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
const propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
1300
|
-
for (const propertyName of propertyNames) {
|
|
1301
|
-
const value = objectValue[propertyName];
|
|
1302
|
-
if (value && typeof value === 'object') {
|
|
1303
|
-
$deepFreeze(value);
|
|
1304
|
-
}
|
|
1305
|
-
}
|
|
1306
|
-
Object.freeze(objectValue);
|
|
1307
|
-
return objectValue;
|
|
1308
|
-
}
|
|
1387
|
+
const ALL_ERRORS = {
|
|
1388
|
+
...PROMPTBOOK_ERRORS,
|
|
1389
|
+
...COMMON_JAVASCRIPT_ERRORS,
|
|
1390
|
+
};
|
|
1309
1391
|
/**
|
|
1310
|
-
*
|
|
1392
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
1311
1393
|
*/
|
|
1312
1394
|
|
|
1313
1395
|
/**
|
|
1314
|
-
*
|
|
1315
|
-
* If not, throws an UnexpectedError with a rich error message and tracking
|
|
1316
|
-
*
|
|
1317
|
-
* - Almost all primitives are serializable BUT:
|
|
1318
|
-
* - `undefined` is not serializable
|
|
1319
|
-
* - `NaN` is not serializable
|
|
1320
|
-
* - Objects and arrays are serializable if all their properties are serializable
|
|
1321
|
-
* - Functions are not serializable
|
|
1322
|
-
* - Circular references are not serializable
|
|
1323
|
-
* - `Date` objects are not serializable
|
|
1324
|
-
* - `Map` and `Set` objects are not serializable
|
|
1325
|
-
* - `RegExp` objects are not serializable
|
|
1326
|
-
* - `Error` objects are not serializable
|
|
1327
|
-
* - `Symbol` objects are not serializable
|
|
1328
|
-
* - And much more...
|
|
1396
|
+
* Deserializes the error object
|
|
1329
1397
|
*
|
|
1330
|
-
* @throws UnexpectedError if the value is not serializable as JSON
|
|
1331
1398
|
* @public exported from `@promptbook/utils`
|
|
1332
1399
|
*/
|
|
1333
|
-
function
|
|
1334
|
-
const {
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
}
|
|
1341
|
-
else if (typeof value === 'boolean') {
|
|
1342
|
-
return;
|
|
1343
|
-
}
|
|
1344
|
-
else if (typeof value === 'number' && !isNaN(value)) {
|
|
1345
|
-
return;
|
|
1346
|
-
}
|
|
1347
|
-
else if (typeof value === 'string') {
|
|
1348
|
-
return;
|
|
1349
|
-
}
|
|
1350
|
-
else if (typeof value === 'symbol') {
|
|
1351
|
-
throw new UnexpectedError(`${name} is symbol`);
|
|
1352
|
-
}
|
|
1353
|
-
else if (typeof value === 'function') {
|
|
1354
|
-
throw new UnexpectedError(`${name} is function`);
|
|
1355
|
-
}
|
|
1356
|
-
else if (typeof value === 'object' && Array.isArray(value)) {
|
|
1357
|
-
for (let i = 0; i < value.length; i++) {
|
|
1358
|
-
checkSerializableAsJson({ name: `${name}[${i}]`, value: value[i], message });
|
|
1359
|
-
}
|
|
1400
|
+
function deserializeError(error) {
|
|
1401
|
+
const { name, stack, id } = error; // Added id
|
|
1402
|
+
let { message } = error;
|
|
1403
|
+
let ErrorClass = ALL_ERRORS[error.name];
|
|
1404
|
+
if (ErrorClass === undefined) {
|
|
1405
|
+
ErrorClass = Error;
|
|
1406
|
+
message = `${name}: ${message}`;
|
|
1360
1407
|
}
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
\`${name}\` is Date
|
|
1365
|
-
|
|
1366
|
-
Use \`string_date_iso8601\` instead
|
|
1408
|
+
if (stack !== undefined && stack !== '') {
|
|
1409
|
+
message = spaceTrim$1((block) => `
|
|
1410
|
+
${block(message)}
|
|
1367
1411
|
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
throw new UnexpectedError(`${name} is Set`);
|
|
1377
|
-
}
|
|
1378
|
-
else if (value instanceof RegExp) {
|
|
1379
|
-
throw new UnexpectedError(`${name} is RegExp`);
|
|
1380
|
-
}
|
|
1381
|
-
else if (value instanceof Error) {
|
|
1382
|
-
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1383
|
-
\`${name}\` is unserialized Error
|
|
1412
|
+
Original stack trace:
|
|
1413
|
+
${block(stack || '')}
|
|
1414
|
+
`);
|
|
1415
|
+
}
|
|
1416
|
+
const deserializedError = new ErrorClass(message);
|
|
1417
|
+
deserializedError.id = id; // Assign id to the error object
|
|
1418
|
+
return deserializedError;
|
|
1419
|
+
}
|
|
1384
1420
|
|
|
1385
|
-
|
|
1421
|
+
/**
|
|
1422
|
+
* Serializes an error into a [🚉] JSON-serializable object
|
|
1423
|
+
*
|
|
1424
|
+
* @public exported from `@promptbook/utils`
|
|
1425
|
+
*/
|
|
1426
|
+
function serializeError(error) {
|
|
1427
|
+
const { name, message, stack } = error;
|
|
1428
|
+
const { id } = error;
|
|
1429
|
+
if (!Object.keys(ALL_ERRORS).includes(name)) {
|
|
1430
|
+
console.error(spaceTrim$1((block) => `
|
|
1386
1431
|
|
|
1387
|
-
|
|
1388
|
-
${block(message || '(nothing)')}
|
|
1432
|
+
Cannot serialize error with name "${name}"
|
|
1389
1433
|
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
else {
|
|
1393
|
-
for (const [subName, subValue] of Object.entries(value)) {
|
|
1394
|
-
if (subValue === undefined) {
|
|
1395
|
-
// Note: undefined in object is serializable - it is just omited
|
|
1396
|
-
continue;
|
|
1397
|
-
}
|
|
1398
|
-
checkSerializableAsJson({ name: `${name}.${subName}`, value: subValue, message });
|
|
1399
|
-
}
|
|
1400
|
-
try {
|
|
1401
|
-
JSON.stringify(value); // <- TODO: [0]
|
|
1402
|
-
}
|
|
1403
|
-
catch (error) {
|
|
1404
|
-
assertsError(error);
|
|
1405
|
-
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1406
|
-
\`${name}\` is not serializable
|
|
1434
|
+
Authors of Promptbook probably forgot to add this error into the list of errors:
|
|
1435
|
+
https://github.com/webgptorg/promptbook/blob/main/src/errors/0-index.ts
|
|
1407
1436
|
|
|
1408
|
-
${block(error.stack || error.message)}
|
|
1409
1437
|
|
|
1410
|
-
|
|
1411
|
-
${block(message || '(nothing)')}
|
|
1412
|
-
`));
|
|
1413
|
-
}
|
|
1414
|
-
/*
|
|
1415
|
-
TODO: [0] Is there some more elegant way to check circular references?
|
|
1416
|
-
const seen = new Set();
|
|
1417
|
-
const stack = [{ value }];
|
|
1418
|
-
while (stack.length > 0) {
|
|
1419
|
-
const { value } = stack.pop()!;
|
|
1420
|
-
if (typeof value === 'object' && value !== null) {
|
|
1421
|
-
if (seen.has(value)) {
|
|
1422
|
-
throw new UnexpectedError(`${name} has circular reference`);
|
|
1423
|
-
}
|
|
1424
|
-
seen.add(value);
|
|
1425
|
-
if (Array.isArray(value)) {
|
|
1426
|
-
stack.push(...value.map((value) => ({ value })));
|
|
1427
|
-
} else {
|
|
1428
|
-
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
1429
|
-
}
|
|
1430
|
-
}
|
|
1431
|
-
}
|
|
1432
|
-
*/
|
|
1433
|
-
return;
|
|
1434
|
-
}
|
|
1435
|
-
}
|
|
1436
|
-
else {
|
|
1437
|
-
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1438
|
-
\`${name}\` is unknown type
|
|
1438
|
+
${block(stack || message)}
|
|
1439
1439
|
|
|
1440
|
-
Additional message for \`${name}\`:
|
|
1441
|
-
${block(message || '(nothing)')}
|
|
1442
1440
|
`));
|
|
1443
1441
|
}
|
|
1442
|
+
return {
|
|
1443
|
+
name: name,
|
|
1444
|
+
message,
|
|
1445
|
+
stack,
|
|
1446
|
+
id, // Include id in the serialized object
|
|
1447
|
+
};
|
|
1444
1448
|
}
|
|
1445
|
-
/**
|
|
1446
|
-
* TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
1447
|
-
* TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
1448
|
-
* Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
1449
|
-
*/
|
|
1450
1449
|
|
|
1451
1450
|
/**
|
|
1452
|
-
*
|
|
1451
|
+
* Async version of Array.forEach
|
|
1453
1452
|
*
|
|
1453
|
+
* @param array - Array to iterate over
|
|
1454
|
+
* @param options - Options for the function
|
|
1455
|
+
* @param callbackfunction - Function to call for each item
|
|
1454
1456
|
* @public exported from `@promptbook/utils`
|
|
1457
|
+
* @deprecated [🪂] Use queues instead
|
|
1455
1458
|
*/
|
|
1456
|
-
function
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1459
|
+
async function forEachAsync(array, options, callbackfunction) {
|
|
1460
|
+
const { maxParallelCount = Infinity } = options;
|
|
1461
|
+
let index = 0;
|
|
1462
|
+
let runningTasks = [];
|
|
1463
|
+
const tasks = [];
|
|
1464
|
+
for (const item of array) {
|
|
1465
|
+
const currentIndex = index++;
|
|
1466
|
+
const task = callbackfunction(item, currentIndex, array);
|
|
1467
|
+
tasks.push(task);
|
|
1468
|
+
runningTasks.push(task);
|
|
1469
|
+
/* not await */ Promise.resolve(task).then(() => {
|
|
1470
|
+
runningTasks = runningTasks.filter((t) => t !== task);
|
|
1471
|
+
});
|
|
1472
|
+
if (maxParallelCount < runningTasks.length) {
|
|
1473
|
+
await Promise.race(runningTasks);
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
await Promise.all(tasks);
|
|
1469
1477
|
}
|
|
1470
|
-
/**
|
|
1471
|
-
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
1472
|
-
*/
|
|
1473
1478
|
|
|
1474
1479
|
/**
|
|
1475
|
-
*
|
|
1476
|
-
*
|
|
1477
|
-
* 1) Checks if the value is serializable as JSON
|
|
1478
|
-
* 2) Makes a deep clone of the object
|
|
1479
|
-
* 2) Orders the object properties
|
|
1480
|
-
* 2) Deeply freezes the cloned object
|
|
1480
|
+
* Function to check if a string is valid CSV
|
|
1481
1481
|
*
|
|
1482
|
-
*
|
|
1482
|
+
* @param value The string to check
|
|
1483
|
+
* @returns `true` if the string is a valid CSV string, false otherwise
|
|
1483
1484
|
*
|
|
1484
|
-
* @returns The same type of object as the input but read-only and re-ordered
|
|
1485
1485
|
* @public exported from `@promptbook/utils`
|
|
1486
1486
|
*/
|
|
1487
|
-
function
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
order: order,
|
|
1500
|
-
});
|
|
1501
|
-
$deepFreeze(orderedValue);
|
|
1502
|
-
return orderedValue;
|
|
1487
|
+
function isValidCsvString(value) {
|
|
1488
|
+
try {
|
|
1489
|
+
// A simple check for CSV format: at least one comma and no invalid characters
|
|
1490
|
+
if (value.includes(',') && /^[\w\s,"']+$/.test(value)) {
|
|
1491
|
+
return true;
|
|
1492
|
+
}
|
|
1493
|
+
return false;
|
|
1494
|
+
}
|
|
1495
|
+
catch (error) {
|
|
1496
|
+
assertsError(error);
|
|
1497
|
+
return false;
|
|
1498
|
+
}
|
|
1503
1499
|
}
|
|
1504
|
-
/**
|
|
1505
|
-
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
1506
|
-
*/
|
|
1507
1500
|
|
|
1508
1501
|
/**
|
|
1509
|
-
*
|
|
1502
|
+
* Function isValidJsonString will tell you if the string is valid JSON or not
|
|
1510
1503
|
*
|
|
1511
|
-
* @
|
|
1512
|
-
|
|
1513
|
-
const REPLACING_NONCE = 'ptbkauk42kV2dzao34faw7FudQUHYPtW';
|
|
1514
|
-
/**
|
|
1515
|
-
* @@@
|
|
1504
|
+
* @param value The string to check
|
|
1505
|
+
* @returns `true` if the string is a valid JSON string, false otherwise
|
|
1516
1506
|
*
|
|
1517
|
-
* @
|
|
1507
|
+
* @public exported from `@promptbook/utils`
|
|
1518
1508
|
*/
|
|
1519
|
-
|
|
1509
|
+
function isValidJsonString(value /* <- [👨⚖️] */) {
|
|
1510
|
+
try {
|
|
1511
|
+
JSON.parse(value);
|
|
1512
|
+
return true;
|
|
1513
|
+
}
|
|
1514
|
+
catch (error) {
|
|
1515
|
+
assertsError(error);
|
|
1516
|
+
if (error.message.includes('Unexpected token')) {
|
|
1517
|
+
return false;
|
|
1518
|
+
}
|
|
1519
|
+
return false;
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1520
1523
|
/**
|
|
1521
|
-
*
|
|
1524
|
+
* Converts a JavaScript Object Notation (JSON) string into an object.
|
|
1522
1525
|
*
|
|
1523
|
-
*
|
|
1524
|
-
*/
|
|
1525
|
-
const RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;
|
|
1526
|
-
/**
|
|
1527
|
-
* The names of the parameters that are reserved for special purposes
|
|
1526
|
+
* Note: This is wrapper around `JSON.parse()` with better error and type handling
|
|
1528
1527
|
*
|
|
1529
|
-
* @public exported from `@promptbook/
|
|
1528
|
+
* @public exported from `@promptbook/utils`
|
|
1530
1529
|
*/
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
'
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1530
|
+
function jsonParse(value) {
|
|
1531
|
+
if (value === undefined) {
|
|
1532
|
+
throw new Error(`Can not parse JSON from undefined value.`);
|
|
1533
|
+
}
|
|
1534
|
+
else if (typeof value !== 'string') {
|
|
1535
|
+
console.error('Can not parse JSON from non-string value.', { text: value });
|
|
1536
|
+
throw new Error(spaceTrim$1(`
|
|
1537
|
+
Can not parse JSON from non-string value.
|
|
1538
|
+
|
|
1539
|
+
The value type: ${typeof value}
|
|
1540
|
+
See more in console.
|
|
1541
|
+
`));
|
|
1542
|
+
}
|
|
1543
|
+
try {
|
|
1544
|
+
return JSON.parse(value);
|
|
1545
|
+
}
|
|
1546
|
+
catch (error) {
|
|
1547
|
+
if (!(error instanceof Error)) {
|
|
1548
|
+
throw error;
|
|
1549
|
+
}
|
|
1550
|
+
throw new Error(spaceTrim$1((block) => `
|
|
1551
|
+
${block(error.message)}
|
|
1552
|
+
|
|
1553
|
+
The JSON text:
|
|
1554
|
+
${block(value)}
|
|
1555
|
+
`));
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1546
1559
|
/**
|
|
1547
|
-
*
|
|
1560
|
+
* Function to check if a string is valid XML
|
|
1561
|
+
*
|
|
1562
|
+
* @param value
|
|
1563
|
+
* @returns `true` if the string is a valid XML string, false otherwise
|
|
1564
|
+
*
|
|
1565
|
+
* @public exported from `@promptbook/utils`
|
|
1548
1566
|
*/
|
|
1567
|
+
function isValidXmlString(value) {
|
|
1568
|
+
try {
|
|
1569
|
+
const parser = new DOMParser();
|
|
1570
|
+
const parsedDocument = parser.parseFromString(value, 'application/xml');
|
|
1571
|
+
const parserError = parsedDocument.getElementsByTagName('parsererror');
|
|
1572
|
+
if (parserError.length > 0) {
|
|
1573
|
+
return false;
|
|
1574
|
+
}
|
|
1575
|
+
return true;
|
|
1576
|
+
}
|
|
1577
|
+
catch (error) {
|
|
1578
|
+
assertsError(error);
|
|
1579
|
+
return false;
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1549
1582
|
|
|
1550
1583
|
/**
|
|
1551
1584
|
* Format either small or big number
|
|
@@ -1982,7 +2015,7 @@ const CountUtils = {
|
|
|
1982
2015
|
PAGES: countPages,
|
|
1983
2016
|
};
|
|
1984
2017
|
/**
|
|
1985
|
-
* TODO: [🧠][🤠] This should be
|
|
2018
|
+
* TODO: [🧠][🤠] This should be probably as part of `TextFormatParser`
|
|
1986
2019
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
1987
2020
|
*/
|
|
1988
2021
|
|
|
@@ -2005,10 +2038,10 @@ function decapitalize(word) {
|
|
|
2005
2038
|
}
|
|
2006
2039
|
|
|
2007
2040
|
/**
|
|
2008
|
-
*
|
|
2041
|
+
* Normalizes a text string to SCREAMING_CASE (all uppercase with underscores).
|
|
2009
2042
|
*
|
|
2010
|
-
* @param text
|
|
2011
|
-
* @returns
|
|
2043
|
+
* @param text The text string to be converted to SCREAMING_CASE format.
|
|
2044
|
+
* @returns The normalized text in SCREAMING_CASE format.
|
|
2012
2045
|
* @example 'HELLO_WORLD'
|
|
2013
2046
|
* @example 'I_LOVE_PROMPTBOOK'
|
|
2014
2047
|
* @public exported from `@promptbook/utils`
|
|
@@ -2093,11 +2126,11 @@ function isValidKeyword(keyword) {
|
|
|
2093
2126
|
}
|
|
2094
2127
|
|
|
2095
2128
|
/**
|
|
2096
|
-
*
|
|
2129
|
+
* Converts a name string into a URI-compatible format.
|
|
2097
2130
|
*
|
|
2098
|
-
* @param name
|
|
2099
|
-
* @returns
|
|
2100
|
-
* @example
|
|
2131
|
+
* @param name The string to be converted to a URI-compatible format.
|
|
2132
|
+
* @returns A URI-compatible string derived from the input name.
|
|
2133
|
+
* @example 'Hello World' -> 'hello-world'
|
|
2101
2134
|
* @public exported from `@promptbook/utils`
|
|
2102
2135
|
*/
|
|
2103
2136
|
function nameToUriPart(name) {
|
|
@@ -2111,11 +2144,11 @@ function nameToUriPart(name) {
|
|
|
2111
2144
|
}
|
|
2112
2145
|
|
|
2113
2146
|
/**
|
|
2114
|
-
*
|
|
2147
|
+
* Converts a given name into URI-compatible parts.
|
|
2115
2148
|
*
|
|
2116
|
-
* @param name
|
|
2117
|
-
* @returns
|
|
2118
|
-
* @example
|
|
2149
|
+
* @param name The name to be converted into URI parts.
|
|
2150
|
+
* @returns An array of URI-compatible parts derived from the name.
|
|
2151
|
+
* @example 'Example Name' -> ['example', 'name']
|
|
2119
2152
|
* @public exported from `@promptbook/utils`
|
|
2120
2153
|
*/
|
|
2121
2154
|
function nameToUriParts(name) {
|
|
@@ -2137,10 +2170,10 @@ function normalizeTo_PascalCase(text) {
|
|
|
2137
2170
|
}
|
|
2138
2171
|
|
|
2139
2172
|
/**
|
|
2140
|
-
*
|
|
2173
|
+
* Normalizes a text string to snake_case format.
|
|
2141
2174
|
*
|
|
2142
|
-
* @param text
|
|
2143
|
-
* @returns
|
|
2175
|
+
* @param text The text string to be converted to snake_case format.
|
|
2176
|
+
* @returns The normalized text in snake_case format.
|
|
2144
2177
|
* @example 'hello_world'
|
|
2145
2178
|
* @example 'i_love_promptbook'
|
|
2146
2179
|
* @public exported from `@promptbook/utils`
|
|
@@ -2192,7 +2225,7 @@ function parseKeywords(input) {
|
|
|
2192
2225
|
*/
|
|
2193
2226
|
|
|
2194
2227
|
/**
|
|
2195
|
-
*
|
|
2228
|
+
* Searches set of keywords for a specific keyword
|
|
2196
2229
|
*
|
|
2197
2230
|
* @param haystack
|
|
2198
2231
|
* @param needle
|
|
@@ -2207,6 +2240,9 @@ function searchKeywords(haystack, needle) {
|
|
|
2207
2240
|
}
|
|
2208
2241
|
return true;
|
|
2209
2242
|
}
|
|
2243
|
+
/**
|
|
2244
|
+
* TODO: Rename to `isKeywordInKeywords`
|
|
2245
|
+
*/
|
|
2210
2246
|
|
|
2211
2247
|
/**
|
|
2212
2248
|
* Adds suffix to the URL
|
|
@@ -2318,9 +2354,9 @@ function parseNumber(value) {
|
|
|
2318
2354
|
/**
|
|
2319
2355
|
* Removes quotes from a string
|
|
2320
2356
|
*
|
|
2321
|
-
* Tip: This is very
|
|
2357
|
+
* Tip: This is very useful for post-processing of the result of the LLM model
|
|
2322
2358
|
* Note: This function removes only the same quotes from the beginning and the end of the string
|
|
2323
|
-
* Note: There are two
|
|
2359
|
+
* Note: There are two similar functions:
|
|
2324
2360
|
* - `removeQuotes` which removes only bounding quotes
|
|
2325
2361
|
* - `unwrapResult` which removes whole introduce sentence
|
|
2326
2362
|
*
|
|
@@ -2332,22 +2368,23 @@ function removeQuotes(text) {
|
|
|
2332
2368
|
if (text.startsWith('"') && text.endsWith('"')) {
|
|
2333
2369
|
return text.slice(1, -1);
|
|
2334
2370
|
}
|
|
2335
|
-
if (text.startsWith('
|
|
2371
|
+
if (text.startsWith("'") && text.endsWith("'")) {
|
|
2336
2372
|
return text.slice(1, -1);
|
|
2337
2373
|
}
|
|
2338
2374
|
return text;
|
|
2339
2375
|
}
|
|
2340
2376
|
|
|
2341
2377
|
/**
|
|
2342
|
-
*
|
|
2378
|
+
* Creates a deep clone of a PipelineJson object, copying all properties explicitly.
|
|
2343
2379
|
*
|
|
2344
|
-
* Note: It is
|
|
2380
|
+
* Note: It is useful for ensuring that modifications to the returned pipeline do not affect the original.
|
|
2345
2381
|
*
|
|
2346
|
-
* @param pipeline
|
|
2382
|
+
* @param pipeline The pipeline to clone.
|
|
2383
|
+
* @returns A new PipelineJson object with the same properties as the input.
|
|
2347
2384
|
* @public exported from `@promptbook/utils`
|
|
2348
2385
|
*/
|
|
2349
2386
|
function clonePipeline(pipeline) {
|
|
2350
|
-
// Note: Not using spread operator (...) because
|
|
2387
|
+
// Note: Not using spread operator (...) because it does not deeply copy nested objects and may miss non-enumerable properties.
|
|
2351
2388
|
const { pipelineUrl, sourceFile, title, bookVersion, description, formfactorName, parameters, tasks, knowledgeSources, knowledgePieces, personas, preparations, sources, } = pipeline;
|
|
2352
2389
|
return {
|
|
2353
2390
|
pipelineUrl,
|
|
@@ -2496,7 +2533,7 @@ function union(...sets) {
|
|
|
2496
2533
|
/**
|
|
2497
2534
|
* Function trimCodeBlock will trim starting and ending code block from the string if it is present.
|
|
2498
2535
|
*
|
|
2499
|
-
* Note: This is
|
|
2536
|
+
* Note: This is useful for post-processing of the result of the chat LLM model
|
|
2500
2537
|
* when the model wraps the result in the (markdown) code block.
|
|
2501
2538
|
*
|
|
2502
2539
|
* @public exported from `@promptbook/utils`
|
|
@@ -2515,7 +2552,7 @@ function trimCodeBlock(value) {
|
|
|
2515
2552
|
/**
|
|
2516
2553
|
* Function trimEndOfCodeBlock will remove ending code block from the string if it is present.
|
|
2517
2554
|
*
|
|
2518
|
-
* Note: This is
|
|
2555
|
+
* Note: This is useful for post-processing of the result of the completion LLM model
|
|
2519
2556
|
* if you want to start code block in the prompt but you don't want to end it in the result.
|
|
2520
2557
|
*
|
|
2521
2558
|
* @public exported from `@promptbook/utils`
|
|
@@ -2530,9 +2567,9 @@ function trimEndOfCodeBlock(value) {
|
|
|
2530
2567
|
/**
|
|
2531
2568
|
* Removes quotes and optional introduce text from a string
|
|
2532
2569
|
*
|
|
2533
|
-
* Tip: This is very
|
|
2570
|
+
* Tip: This is very useful for post-processing of the result of the LLM model
|
|
2534
2571
|
* Note: This function trims the text and removes whole introduce sentence if it is present
|
|
2535
|
-
* Note: There are two
|
|
2572
|
+
* Note: There are two similar functions:
|
|
2536
2573
|
* - `removeQuotes` which removes only bounding quotes
|
|
2537
2574
|
* - `unwrapResult` which removes whole introduce sentence
|
|
2538
2575
|
*
|
|
@@ -2633,10 +2670,10 @@ function isRootPath(value) {
|
|
|
2633
2670
|
*/
|
|
2634
2671
|
|
|
2635
2672
|
/**
|
|
2636
|
-
*
|
|
2673
|
+
* Checks if the given value is a valid JavaScript identifier name.
|
|
2637
2674
|
*
|
|
2638
|
-
* @param javascriptName
|
|
2639
|
-
* @returns
|
|
2675
|
+
* @param javascriptName The value to check for JavaScript identifier validity.
|
|
2676
|
+
* @returns `true` if the value is a valid JavaScript name, false otherwise.
|
|
2640
2677
|
* @public exported from `@promptbook/utils`
|
|
2641
2678
|
*/
|
|
2642
2679
|
function isValidJavascriptName(javascriptName) {
|
|
@@ -2649,7 +2686,7 @@ function isValidJavascriptName(javascriptName) {
|
|
|
2649
2686
|
/**
|
|
2650
2687
|
* Tests if given string is valid semantic version
|
|
2651
2688
|
*
|
|
2652
|
-
* Note: There are two
|
|
2689
|
+
* Note: There are two similar functions:
|
|
2653
2690
|
* - `isValidSemanticVersion` which tests any semantic version
|
|
2654
2691
|
* - `isValidPromptbookVersion` *(this one)* which tests just Promptbook versions
|
|
2655
2692
|
*
|
|
@@ -2671,7 +2708,7 @@ function isValidSemanticVersion(version) {
|
|
|
2671
2708
|
*
|
|
2672
2709
|
* @see https://www.npmjs.com/package/promptbook?activeTab=versions
|
|
2673
2710
|
* Note: When you are using for example promptbook 2.0.0 and there already is promptbook 3.0.0 it don`t know about it.
|
|
2674
|
-
* Note: There are two
|
|
2711
|
+
* Note: There are two similar functions:
|
|
2675
2712
|
* - `isValidSemanticVersion` which tests any semantic version
|
|
2676
2713
|
* - `isValidPromptbookVersion` *(this one)* which tests just Promptbook versions
|
|
2677
2714
|
*
|
|
@@ -2691,7 +2728,7 @@ function isValidPromptbookVersion(version) {
|
|
|
2691
2728
|
/**
|
|
2692
2729
|
* Checks if an URL is reserved for private networks or localhost.
|
|
2693
2730
|
*
|
|
2694
|
-
* Note: There are two
|
|
2731
|
+
* Note: There are two similar functions:
|
|
2695
2732
|
* - `isUrlOnPrivateNetwork` which tests full URL
|
|
2696
2733
|
* - `isHostnameOnPrivateNetwork` *(this one)* which tests just hostname
|
|
2697
2734
|
*
|
|
@@ -2724,7 +2761,7 @@ function isHostnameOnPrivateNetwork(hostname) {
|
|
|
2724
2761
|
/**
|
|
2725
2762
|
* Checks if an IP address or hostname is reserved for private networks or localhost.
|
|
2726
2763
|
*
|
|
2727
|
-
* Note: There are two
|
|
2764
|
+
* Note: There are two similar functions:
|
|
2728
2765
|
* - `isUrlOnPrivateNetwork` *(this one)* which tests full URL
|
|
2729
2766
|
* - `isHostnameOnPrivateNetwork` which tests just hostname
|
|
2730
2767
|
*
|
|
@@ -2742,7 +2779,7 @@ function isUrlOnPrivateNetwork(url) {
|
|
|
2742
2779
|
/**
|
|
2743
2780
|
* Tests if given string is valid pipeline URL URL.
|
|
2744
2781
|
*
|
|
2745
|
-
* Note: There are two
|
|
2782
|
+
* Note: There are two similar functions:
|
|
2746
2783
|
* - `isValidUrl` which tests any URL
|
|
2747
2784
|
* - `isValidPipelineUrl` *(this one)* which tests just pipeline URL
|
|
2748
2785
|
*
|