@promptbook/javascript 0.92.0-3 → 0.92.0-31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/index.es.js +507 -499
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/_packages/browser.index.d.ts +2 -0
- package/esm/typings/src/_packages/core.index.d.ts +22 -6
- package/esm/typings/src/_packages/deepseek.index.d.ts +2 -0
- package/esm/typings/src/_packages/google.index.d.ts +2 -0
- package/esm/typings/src/_packages/types.index.d.ts +4 -2
- package/esm/typings/src/_packages/utils.index.d.ts +2 -0
- package/esm/typings/src/cli/common/$provideLlmToolsForCli.d.ts +1 -1
- package/esm/typings/src/collection/PipelineCollection.d.ts +0 -2
- package/esm/typings/src/collection/SimplePipelineCollection.d.ts +1 -1
- package/esm/typings/src/commands/FOREACH/ForeachJson.d.ts +6 -6
- package/esm/typings/src/commands/FOREACH/foreachCommandParser.d.ts +0 -2
- package/esm/typings/src/commands/FORMFACTOR/formfactorCommandParser.d.ts +1 -1
- package/esm/typings/src/commands/_BOILERPLATE/boilerplateCommandParser.d.ts +1 -1
- package/esm/typings/src/commands/_common/types/CommandParser.d.ts +36 -28
- package/esm/typings/src/config.d.ts +41 -11
- package/esm/typings/src/constants.d.ts +43 -2
- package/esm/typings/src/conversion/archive/loadArchive.d.ts +2 -2
- package/esm/typings/src/errors/0-BoilerplateError.d.ts +2 -2
- package/esm/typings/src/executables/$provideExecutablesForNode.d.ts +1 -1
- package/esm/typings/src/executables/apps/locateLibreoffice.d.ts +2 -1
- package/esm/typings/src/executables/apps/locatePandoc.d.ts +2 -1
- package/esm/typings/src/executables/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/LlmExecutionToolsConstructor.d.ts +2 -1
- package/esm/typings/src/execution/PipelineExecutorResult.d.ts +4 -2
- package/esm/typings/src/execution/createPipelineExecutor/$OngoingTaskResult.d.ts +12 -9
- package/esm/typings/src/execution/createPipelineExecutor/10-executePipeline.d.ts +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 +20 -14
- package/esm/typings/src/execution/createPipelineExecutor/computeCosineSimilarity.d.ts +13 -0
- package/esm/typings/src/execution/createPipelineExecutor/filterJustOutputParameters.d.ts +7 -6
- package/esm/typings/src/execution/createPipelineExecutor/getContextForTask.d.ts +5 -1
- package/esm/typings/src/execution/createPipelineExecutor/getExamplesForTask.d.ts +1 -1
- package/esm/typings/src/execution/createPipelineExecutor/getKnowledgeForTask.d.ts +21 -5
- package/esm/typings/src/execution/createPipelineExecutor/getReservedParametersForTask.d.ts +19 -5
- package/esm/typings/src/execution/createPipelineExecutor/knowledgePiecesToString.d.ts +9 -0
- package/esm/typings/src/execution/translation/automatic-translate/automatic-translators/LindatAutomaticTranslator.d.ts +4 -4
- package/esm/typings/src/execution/utils/checkExpectations.d.ts +1 -1
- package/esm/typings/src/execution/utils/uncertainNumber.d.ts +3 -2
- package/esm/typings/src/formats/_common/{FormatDefinition.d.ts → FormatParser.d.ts} +8 -6
- package/esm/typings/src/formats/_common/FormatSubvalueParser.d.ts +66 -0
- package/esm/typings/src/formats/csv/CsvFormatParser.d.ts +17 -0
- package/esm/typings/src/formats/csv/CsvSettings.d.ts +2 -2
- package/esm/typings/src/formats/csv/utils/csvParse.d.ts +12 -0
- package/esm/typings/src/formats/csv/utils/isValidCsvString.d.ts +1 -1
- package/esm/typings/src/formats/index.d.ts +2 -2
- package/esm/typings/src/formats/json/{JsonFormatDefinition.d.ts → JsonFormatParser.d.ts} +6 -6
- package/esm/typings/src/formats/json/utils/isValidJsonString.d.ts +1 -1
- package/esm/typings/src/formats/json/utils/jsonParse.d.ts +8 -0
- package/esm/typings/src/formats/text/{TextFormatDefinition.d.ts → TextFormatParser.d.ts} +7 -7
- package/esm/typings/src/formats/xml/XmlFormatParser.d.ts +19 -0
- package/esm/typings/src/formats/xml/utils/isValidXmlString.d.ts +1 -1
- package/esm/typings/src/formfactors/_boilerplate/BoilerplateFormfactorDefinition.d.ts +3 -2
- package/esm/typings/src/formfactors/_common/AbstractFormfactorDefinition.d.ts +16 -7
- package/esm/typings/src/formfactors/_common/FormfactorDefinition.d.ts +3 -1
- package/esm/typings/src/formfactors/_common/string_formfactor_name.d.ts +2 -1
- package/esm/typings/src/formfactors/chatbot/ChatbotFormfactorDefinition.d.ts +2 -2
- package/esm/typings/src/formfactors/completion/CompletionFormfactorDefinition.d.ts +29 -0
- package/esm/typings/src/formfactors/generator/GeneratorFormfactorDefinition.d.ts +2 -1
- package/esm/typings/src/formfactors/generic/GenericFormfactorDefinition.d.ts +2 -2
- package/esm/typings/src/formfactors/index.d.ts +33 -8
- package/esm/typings/src/formfactors/matcher/MatcherFormfactorDefinition.d.ts +4 -2
- package/esm/typings/src/formfactors/sheets/SheetsFormfactorDefinition.d.ts +3 -2
- package/esm/typings/src/formfactors/translator/TranslatorFormfactorDefinition.d.ts +3 -2
- package/esm/typings/src/high-level-abstractions/index.d.ts +2 -2
- package/esm/typings/src/llm-providers/_common/register/$llmToolsMetadataRegister.d.ts +3 -3
- package/esm/typings/src/llm-providers/_common/register/$llmToolsRegister.d.ts +3 -3
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsConfigurationFromEnv.d.ts +4 -4
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForTestingAndScriptsAndPlayground.d.ts +4 -3
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsFromEnv.d.ts +17 -4
- package/esm/typings/src/llm-providers/_common/register/LlmToolsConfiguration.d.ts +11 -4
- package/esm/typings/src/llm-providers/_common/register/LlmToolsMetadata.d.ts +27 -5
- package/esm/typings/src/llm-providers/_common/register/LlmToolsOptions.d.ts +9 -2
- package/esm/typings/src/llm-providers/_common/register/createLlmToolsFromConfiguration.d.ts +12 -3
- package/esm/typings/src/llm-providers/_common/utils/cache/CacheItem.d.ts +10 -5
- package/esm/typings/src/llm-providers/_common/utils/cache/CacheLlmToolsOptions.d.ts +5 -3
- package/esm/typings/src/llm-providers/_common/utils/cache/cacheLlmTools.d.ts +3 -3
- package/esm/typings/src/llm-providers/_common/utils/count-total-usage/limitTotalUsage.d.ts +5 -5
- package/esm/typings/src/llm-providers/anthropic-claude/anthropic-claude-models.d.ts +1 -1
- package/esm/typings/src/llm-providers/azure-openai/AzureOpenAiExecutionTools.d.ts +4 -0
- package/esm/typings/src/llm-providers/deepseek/deepseek-models.d.ts +23 -0
- package/esm/typings/src/llm-providers/google/google-models.d.ts +23 -0
- package/esm/typings/src/llm-providers/openai/OpenAiExecutionTools.d.ts +4 -0
- package/esm/typings/src/llm-providers/openai/openai-models.d.ts +1 -1
- package/esm/typings/src/llm-providers/openai/register-configuration.d.ts +2 -2
- package/esm/typings/src/llm-providers/openai/register-constructor.d.ts +2 -2
- package/esm/typings/src/migrations/migratePipeline.d.ts +9 -0
- package/esm/typings/src/other/templates/getBookTemplates.d.ts +2 -2
- package/esm/typings/src/personas/preparePersona.d.ts +1 -1
- package/esm/typings/src/pipeline/PipelineInterface/PipelineInterface.d.ts +3 -3
- package/esm/typings/src/pipeline/PipelineInterface/constants.d.ts +1 -1
- package/esm/typings/src/pipeline/PipelineInterface/getPipelineInterface.d.ts +1 -1
- package/esm/typings/src/pipeline/PipelineInterface/isPipelineImplementingInterface.d.ts +5 -4
- package/esm/typings/src/pipeline/PipelineInterface/isPipelineInterfacesEqual.d.ts +1 -1
- package/esm/typings/src/pipeline/PipelineJson/CommonTaskJson.d.ts +9 -6
- package/esm/typings/src/pipeline/PipelineJson/PersonaJson.d.ts +4 -2
- package/esm/typings/src/pipeline/PipelineJson/PipelineJson.d.ts +3 -2
- package/esm/typings/src/pipeline/PipelineString.d.ts +3 -1
- package/esm/typings/src/pipeline/book-notation.d.ts +2 -2
- package/esm/typings/src/postprocessing/utils/extractJsonBlock.d.ts +1 -1
- package/esm/typings/src/prepare/prepareTasks.d.ts +7 -4
- package/esm/typings/src/remote-server/openapi-types.d.ts +348 -6
- package/esm/typings/src/remote-server/openapi.d.ts +398 -4
- package/esm/typings/src/remote-server/types/RemoteServerOptions.d.ts +2 -1
- package/esm/typings/src/scrapers/_boilerplate/BoilerplateScraper.d.ts +3 -3
- package/esm/typings/src/scrapers/_boilerplate/createBoilerplateScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/_boilerplate/register-metadata.d.ts +1 -1
- package/esm/typings/src/scrapers/_common/Converter.d.ts +3 -1
- package/esm/typings/src/scrapers/_common/Scraper.d.ts +4 -3
- package/esm/typings/src/scrapers/_common/ScraperIntermediateSource.d.ts +4 -2
- package/esm/typings/src/scrapers/_common/register/$provideFilesystemForNode.d.ts +2 -1
- package/esm/typings/src/scrapers/_common/register/$provideScrapersForBrowser.d.ts +6 -3
- package/esm/typings/src/scrapers/_common/register/$provideScrapersForNode.d.ts +3 -5
- package/esm/typings/src/scrapers/_common/register/$scrapersMetadataRegister.d.ts +3 -3
- package/esm/typings/src/scrapers/_common/register/$scrapersRegister.d.ts +3 -2
- package/esm/typings/src/scrapers/_common/register/ScraperAndConverterMetadata.d.ts +8 -5
- package/esm/typings/src/scrapers/_common/register/ScraperConstructor.d.ts +2 -1
- package/esm/typings/src/scrapers/_common/utils/getScraperIntermediateSource.d.ts +6 -5
- package/esm/typings/src/scrapers/_common/utils/makeKnowledgeSourceHandler.d.ts +3 -1
- package/esm/typings/src/scrapers/document/createDocumentScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/document-legacy/createLegacyDocumentScraper.d.ts +2 -1
- package/esm/typings/src/scrapers/markdown/createMarkdownScraper.d.ts +4 -1
- package/esm/typings/src/scrapers/markitdown/MarkitdownScraper.d.ts +1 -1
- package/esm/typings/src/scrapers/pdf/createPdfScraper.d.ts +2 -1
- package/esm/typings/src/scrapers/website/createWebsiteScraper.d.ts +3 -4
- package/esm/typings/src/scripting/javascript/postprocessing-functions.d.ts +5 -1
- package/esm/typings/src/storage/file-cache-storage/FileCacheStorage.d.ts +12 -5
- package/esm/typings/src/storage/file-cache-storage/FileCacheStorageOptions.d.ts +4 -2
- package/esm/typings/src/storage/file-cache-storage/utils/nameToSubfolderPath.d.ts +2 -1
- package/esm/typings/src/storage/local-storage/getIndexedDbStorage.d.ts +10 -0
- package/esm/typings/src/storage/local-storage/utils/makePromptbookStorageFromIndexedDb.d.ts +7 -0
- package/esm/typings/src/storage/local-storage/utils/makePromptbookStorageFromWebStorage.d.ts +2 -1
- package/esm/typings/src/types/IntermediateFilesStrategy.d.ts +2 -1
- package/esm/typings/src/types/ModelVariant.d.ts +5 -5
- package/esm/typings/src/types/typeAliases.d.ts +17 -13
- package/esm/typings/src/utils/$Register.d.ts +8 -7
- package/esm/typings/src/utils/editable/edit-pipeline-string/addPipelineCommand.d.ts +2 -2
- package/esm/typings/src/utils/editable/edit-pipeline-string/deflatePipeline.d.ts +4 -1
- package/esm/typings/src/utils/editable/utils/isFlatPipeline.d.ts +2 -1
- package/esm/typings/src/utils/environment/$getGlobalScope.d.ts +2 -1
- package/esm/typings/src/utils/expectation-counters/index.d.ts +1 -1
- package/esm/typings/src/utils/markdown/extractAllListItemsFromMarkdown.d.ts +1 -1
- package/esm/typings/src/utils/normalization/nameToUriPart.d.ts +4 -4
- package/esm/typings/src/utils/normalization/nameToUriParts.d.ts +4 -4
- package/esm/typings/src/utils/normalization/normalize-to-kebab-case.d.ts +3 -3
- package/esm/typings/src/utils/normalization/normalizeTo_SCREAMING_CASE.d.ts +3 -3
- package/esm/typings/src/utils/normalization/normalizeTo_camelCase.d.ts +4 -4
- package/esm/typings/src/utils/normalization/normalizeTo_snake_case.d.ts +3 -3
- package/esm/typings/src/utils/normalization/removeDiacritics.d.ts +3 -3
- package/esm/typings/src/utils/normalization/searchKeywords.d.ts +4 -1
- package/esm/typings/src/utils/normalization/titleToName.d.ts +4 -4
- package/esm/typings/src/utils/organization/empty_object.d.ts +2 -2
- package/esm/typings/src/utils/organization/just_empty_object.d.ts +4 -4
- package/esm/typings/src/utils/parameters/mapAvailableToExpectedParameters.d.ts +7 -7
- package/esm/typings/src/utils/serialization/clonePipeline.d.ts +4 -3
- package/esm/typings/src/utils/serialization/deepClone.d.ts +5 -1
- package/esm/typings/src/utils/validators/javascriptName/isValidJavascriptName.d.ts +3 -3
- package/esm/typings/src/utils/validators/parameterName/validateParameterName.d.ts +5 -4
- package/esm/typings/src/version.d.ts +2 -1
- package/package.json +2 -2
- package/umd/index.umd.js +507 -499
- package/umd/index.umd.js.map +1 -1
- package/esm/typings/src/formats/_common/FormatSubvalueDefinition.d.ts +0 -31
- package/esm/typings/src/formats/csv/CsvFormatDefinition.d.ts +0 -17
- package/esm/typings/src/formats/xml/XmlFormatDefinition.d.ts +0 -19
package/esm/index.es.js
CHANGED
|
@@ -19,7 +19,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
|
|
|
19
19
|
* @generated
|
|
20
20
|
* @see https://github.com/webgptorg/promptbook
|
|
21
21
|
*/
|
|
22
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.92.0-
|
|
22
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.92.0-31';
|
|
23
23
|
/**
|
|
24
24
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
25
25
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -75,7 +75,7 @@ const VALUE_STRINGS = {
|
|
|
75
75
|
const SMALL_NUMBER = 0.001;
|
|
76
76
|
// <- TODO: [🧜♂️]
|
|
77
77
|
/**
|
|
78
|
-
*
|
|
78
|
+
* Default settings for parsing and generating CSV files in Promptbook.
|
|
79
79
|
*
|
|
80
80
|
* @public exported from `@promptbook/core`
|
|
81
81
|
*/
|
|
@@ -90,6 +90,48 @@ Object.freeze({
|
|
|
90
90
|
* TODO: [🧠][🧜♂️] Maybe join remoteServerUrl and path into single value
|
|
91
91
|
*/
|
|
92
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Orders JSON object by keys
|
|
95
|
+
*
|
|
96
|
+
* @returns The same type of object as the input re-ordered
|
|
97
|
+
* @public exported from `@promptbook/utils`
|
|
98
|
+
*/
|
|
99
|
+
function orderJson(options) {
|
|
100
|
+
const { value, order } = options;
|
|
101
|
+
const orderedValue = {
|
|
102
|
+
...(order === undefined ? {} : Object.fromEntries(order.map((key) => [key, undefined]))),
|
|
103
|
+
...value,
|
|
104
|
+
};
|
|
105
|
+
return orderedValue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Freezes the given object and all its nested objects recursively
|
|
110
|
+
*
|
|
111
|
+
* Note: `$` is used to indicate that this function is not a pure function - it mutates given object
|
|
112
|
+
* Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
|
|
113
|
+
*
|
|
114
|
+
* @returns The same object as the input, but deeply frozen
|
|
115
|
+
* @public exported from `@promptbook/utils`
|
|
116
|
+
*/
|
|
117
|
+
function $deepFreeze(objectValue) {
|
|
118
|
+
if (Array.isArray(objectValue)) {
|
|
119
|
+
return Object.freeze(objectValue.map((item) => $deepFreeze(item)));
|
|
120
|
+
}
|
|
121
|
+
const propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
122
|
+
for (const propertyName of propertyNames) {
|
|
123
|
+
const value = objectValue[propertyName];
|
|
124
|
+
if (value && typeof value === 'object') {
|
|
125
|
+
$deepFreeze(value);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
Object.freeze(objectValue);
|
|
129
|
+
return objectValue;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
133
|
+
*/
|
|
134
|
+
|
|
93
135
|
/**
|
|
94
136
|
* Make error report URL for the given error
|
|
95
137
|
*
|
|
@@ -159,70 +201,341 @@ class UnexpectedError extends Error {
|
|
|
159
201
|
}
|
|
160
202
|
|
|
161
203
|
/**
|
|
162
|
-
*
|
|
204
|
+
* This error type indicates that somewhere in the code non-Error object was thrown and it was wrapped into the `WrappedError`
|
|
163
205
|
*
|
|
164
|
-
* @
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
206
|
+
* @public exported from `@promptbook/core`
|
|
207
|
+
*/
|
|
208
|
+
class WrappedError extends Error {
|
|
209
|
+
constructor(whatWasThrown) {
|
|
210
|
+
const tag = `[🤮]`;
|
|
211
|
+
console.error(tag, whatWasThrown);
|
|
212
|
+
super(spaceTrim$1(`
|
|
213
|
+
Non-Error object was thrown
|
|
214
|
+
|
|
215
|
+
Note: Look for ${tag} in the console for more details
|
|
216
|
+
Please report issue on ${ADMIN_EMAIL}
|
|
217
|
+
`));
|
|
218
|
+
this.name = 'WrappedError';
|
|
219
|
+
Object.setPrototypeOf(this, WrappedError.prototype);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Helper used in catch blocks to assert that the error is an instance of `Error`
|
|
225
|
+
*
|
|
226
|
+
* @param whatWasThrown Any object that was thrown
|
|
227
|
+
* @returns Nothing if the error is an instance of `Error`
|
|
228
|
+
* @throws `WrappedError` or `UnexpectedError` if the error is not standard
|
|
229
|
+
*
|
|
230
|
+
* @private within the repository
|
|
231
|
+
*/
|
|
232
|
+
function assertsError(whatWasThrown) {
|
|
233
|
+
// Case 1: Handle error which was rethrown as `WrappedError`
|
|
234
|
+
if (whatWasThrown instanceof WrappedError) {
|
|
235
|
+
const wrappedError = whatWasThrown;
|
|
236
|
+
throw wrappedError;
|
|
237
|
+
}
|
|
238
|
+
// Case 2: Handle unexpected errors
|
|
239
|
+
if (whatWasThrown instanceof UnexpectedError) {
|
|
240
|
+
const unexpectedError = whatWasThrown;
|
|
241
|
+
throw unexpectedError;
|
|
242
|
+
}
|
|
243
|
+
// Case 3: Handle standard errors - keep them up to consumer
|
|
244
|
+
if (whatWasThrown instanceof Error) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
// Case 4: Handle non-standard errors - wrap them into `WrappedError` and throw
|
|
248
|
+
throw new WrappedError(whatWasThrown);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Checks if the value is [🚉] serializable as JSON
|
|
253
|
+
* If not, throws an UnexpectedError with a rich error message and tracking
|
|
254
|
+
*
|
|
255
|
+
* - Almost all primitives are serializable BUT:
|
|
256
|
+
* - `undefined` is not serializable
|
|
257
|
+
* - `NaN` is not serializable
|
|
258
|
+
* - Objects and arrays are serializable if all their properties are serializable
|
|
259
|
+
* - Functions are not serializable
|
|
260
|
+
* - Circular references are not serializable
|
|
261
|
+
* - `Date` objects are not serializable
|
|
262
|
+
* - `Map` and `Set` objects are not serializable
|
|
263
|
+
* - `RegExp` objects are not serializable
|
|
264
|
+
* - `Error` objects are not serializable
|
|
265
|
+
* - `Symbol` objects are not serializable
|
|
266
|
+
* - And much more...
|
|
267
|
+
*
|
|
268
|
+
* @throws UnexpectedError if the value is not serializable as JSON
|
|
169
269
|
* @public exported from `@promptbook/utils`
|
|
170
270
|
*/
|
|
171
|
-
function
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
271
|
+
function checkSerializableAsJson(options) {
|
|
272
|
+
const { value, name, message } = options;
|
|
273
|
+
if (value === undefined) {
|
|
274
|
+
throw new UnexpectedError(`${name} is undefined`);
|
|
275
|
+
}
|
|
276
|
+
else if (value === null) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
else if (typeof value === 'boolean') {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
else if (typeof value === 'number' && !isNaN(value)) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
else if (typeof value === 'string') {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
else if (typeof value === 'symbol') {
|
|
289
|
+
throw new UnexpectedError(`${name} is symbol`);
|
|
290
|
+
}
|
|
291
|
+
else if (typeof value === 'function') {
|
|
292
|
+
throw new UnexpectedError(`${name} is function`);
|
|
293
|
+
}
|
|
294
|
+
else if (typeof value === 'object' && Array.isArray(value)) {
|
|
295
|
+
for (let i = 0; i < value.length; i++) {
|
|
296
|
+
checkSerializableAsJson({ name: `${name}[${i}]`, value: value[i], message });
|
|
180
297
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
298
|
+
}
|
|
299
|
+
else if (typeof value === 'object') {
|
|
300
|
+
if (value instanceof Date) {
|
|
301
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
302
|
+
\`${name}\` is Date
|
|
303
|
+
|
|
304
|
+
Use \`string_date_iso8601\` instead
|
|
305
|
+
|
|
306
|
+
Additional message for \`${name}\`:
|
|
307
|
+
${block(message || '(nothing)')}
|
|
308
|
+
`));
|
|
184
309
|
}
|
|
185
|
-
else if (
|
|
186
|
-
|
|
187
|
-
normalizedChar = char;
|
|
310
|
+
else if (value instanceof Map) {
|
|
311
|
+
throw new UnexpectedError(`${name} is Map`);
|
|
188
312
|
}
|
|
189
|
-
else {
|
|
190
|
-
|
|
191
|
-
normalizedChar = '';
|
|
313
|
+
else if (value instanceof Set) {
|
|
314
|
+
throw new UnexpectedError(`${name} is Set`);
|
|
192
315
|
}
|
|
193
|
-
if (
|
|
194
|
-
|
|
195
|
-
normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
|
|
196
|
-
}
|
|
316
|
+
else if (value instanceof RegExp) {
|
|
317
|
+
throw new UnexpectedError(`${name} is RegExp`);
|
|
197
318
|
}
|
|
198
|
-
else if (
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
319
|
+
else if (value instanceof Error) {
|
|
320
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
321
|
+
\`${name}\` is unserialized Error
|
|
322
|
+
|
|
323
|
+
Use function \`serializeError\`
|
|
324
|
+
|
|
325
|
+
Additional message for \`${name}\`:
|
|
326
|
+
${block(message || '(nothing)')}
|
|
327
|
+
|
|
328
|
+
`));
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
for (const [subName, subValue] of Object.entries(value)) {
|
|
332
|
+
if (subValue === undefined) {
|
|
333
|
+
// Note: undefined in object is serializable - it is just omited
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
checkSerializableAsJson({ name: `${name}.${subName}`, value: subValue, message });
|
|
337
|
+
}
|
|
338
|
+
try {
|
|
339
|
+
JSON.stringify(value); // <- TODO: [0]
|
|
340
|
+
}
|
|
341
|
+
catch (error) {
|
|
342
|
+
assertsError(error);
|
|
343
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
344
|
+
\`${name}\` is not serializable
|
|
345
|
+
|
|
346
|
+
${block(error.stack || error.message)}
|
|
347
|
+
|
|
348
|
+
Additional message for \`${name}\`:
|
|
349
|
+
${block(message || '(nothing)')}
|
|
350
|
+
`));
|
|
351
|
+
}
|
|
352
|
+
/*
|
|
353
|
+
TODO: [0] Is there some more elegant way to check circular references?
|
|
354
|
+
const seen = new Set();
|
|
355
|
+
const stack = [{ value }];
|
|
356
|
+
while (stack.length > 0) {
|
|
357
|
+
const { value } = stack.pop()!;
|
|
358
|
+
if (typeof value === 'object' && value !== null) {
|
|
359
|
+
if (seen.has(value)) {
|
|
360
|
+
throw new UnexpectedError(`${name} has circular reference`);
|
|
361
|
+
}
|
|
362
|
+
seen.add(value);
|
|
363
|
+
if (Array.isArray(value)) {
|
|
364
|
+
stack.push(...value.map((value) => ({ value })));
|
|
365
|
+
} else {
|
|
366
|
+
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
*/
|
|
371
|
+
return;
|
|
203
372
|
}
|
|
204
|
-
normalizedName += normalizedChar;
|
|
205
|
-
lastCharType = charType;
|
|
206
373
|
}
|
|
207
|
-
|
|
374
|
+
else {
|
|
375
|
+
throw new UnexpectedError(spaceTrim((block) => `
|
|
376
|
+
\`${name}\` is unknown type
|
|
377
|
+
|
|
378
|
+
Additional message for \`${name}\`:
|
|
379
|
+
${block(message || '(nothing)')}
|
|
380
|
+
`));
|
|
381
|
+
}
|
|
208
382
|
}
|
|
209
383
|
/**
|
|
210
|
-
* TODO:
|
|
384
|
+
* TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
385
|
+
* TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
386
|
+
* Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
211
387
|
*/
|
|
212
388
|
|
|
213
389
|
/**
|
|
214
|
-
*
|
|
390
|
+
* Creates a deep clone of the given object
|
|
215
391
|
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
392
|
+
* Note: This method only works for objects that are fully serializable to JSON and do not contain functions, Dates, or special types.
|
|
393
|
+
*
|
|
394
|
+
* @param objectValue The object to clone.
|
|
395
|
+
* @returns A deep, writable clone of the input object.
|
|
218
396
|
* @public exported from `@promptbook/utils`
|
|
219
397
|
*/
|
|
220
|
-
function
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
398
|
+
function deepClone(objectValue) {
|
|
399
|
+
return JSON.parse(JSON.stringify(objectValue));
|
|
400
|
+
/*
|
|
401
|
+
TODO: [🧠] Is there a better implementation?
|
|
402
|
+
> const propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
403
|
+
> for (const propertyName of propertyNames) {
|
|
404
|
+
> const value = (objectValue as really_any)[propertyName];
|
|
405
|
+
> if (value && typeof value === 'object') {
|
|
406
|
+
> deepClone(value);
|
|
407
|
+
> }
|
|
408
|
+
> }
|
|
409
|
+
> return Object.assign({}, objectValue);
|
|
410
|
+
*/
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
414
|
+
*/
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Utility to export a JSON object from a function
|
|
418
|
+
*
|
|
419
|
+
* 1) Checks if the value is serializable as JSON
|
|
420
|
+
* 2) Makes a deep clone of the object
|
|
421
|
+
* 2) Orders the object properties
|
|
422
|
+
* 2) Deeply freezes the cloned object
|
|
423
|
+
*
|
|
424
|
+
* Note: This function does not mutates the given object
|
|
425
|
+
*
|
|
426
|
+
* @returns The same type of object as the input but read-only and re-ordered
|
|
427
|
+
* @public exported from `@promptbook/utils`
|
|
428
|
+
*/
|
|
429
|
+
function exportJson(options) {
|
|
430
|
+
const { name, value, order, message } = options;
|
|
431
|
+
checkSerializableAsJson({ name, value, message });
|
|
432
|
+
const orderedValue =
|
|
433
|
+
// TODO: Fix error "Type instantiation is excessively deep and possibly infinite."
|
|
434
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
435
|
+
// @ts-ignore
|
|
436
|
+
order === undefined
|
|
437
|
+
? deepClone(value)
|
|
438
|
+
: orderJson({
|
|
439
|
+
value: value,
|
|
440
|
+
// <- Note: checkSerializableAsJson asserts that the value is serializable as JSON
|
|
441
|
+
order: order,
|
|
442
|
+
});
|
|
443
|
+
$deepFreeze(orderedValue);
|
|
444
|
+
return orderedValue;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
448
|
+
*/
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* The names of the parameters that are reserved for special purposes
|
|
452
|
+
*
|
|
453
|
+
* @public exported from `@promptbook/core`
|
|
454
|
+
*/
|
|
455
|
+
exportJson({
|
|
456
|
+
name: 'RESERVED_PARAMETER_NAMES',
|
|
457
|
+
message: `The names of the parameters that are reserved for special purposes`,
|
|
458
|
+
value: [
|
|
459
|
+
'content',
|
|
460
|
+
'context',
|
|
461
|
+
'knowledge',
|
|
462
|
+
'examples',
|
|
463
|
+
'modelName',
|
|
464
|
+
'currentDate',
|
|
465
|
+
// <- TODO: list here all command names
|
|
466
|
+
// <- TODO: Add more like 'date', 'modelName',...
|
|
467
|
+
// <- TODO: Add [emoji] + instructions ACRY when adding new reserved parameter
|
|
468
|
+
],
|
|
469
|
+
});
|
|
470
|
+
/**
|
|
471
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
472
|
+
*/
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Normalizes a given text to camelCase format.
|
|
476
|
+
*
|
|
477
|
+
* @param text The text to be normalized.
|
|
478
|
+
* @param _isFirstLetterCapital Whether the first letter should be capitalized.
|
|
479
|
+
* @returns The camelCase formatted string.
|
|
480
|
+
* @example 'helloWorld'
|
|
481
|
+
* @example 'iLovePromptbook'
|
|
482
|
+
* @public exported from `@promptbook/utils`
|
|
483
|
+
*/
|
|
484
|
+
function normalizeTo_camelCase(text, _isFirstLetterCapital = false) {
|
|
485
|
+
let charType;
|
|
486
|
+
let lastCharType = null;
|
|
487
|
+
let normalizedName = '';
|
|
488
|
+
for (const char of text) {
|
|
489
|
+
let normalizedChar;
|
|
490
|
+
if (/^[a-z]$/.test(char)) {
|
|
491
|
+
charType = 'LOWERCASE';
|
|
492
|
+
normalizedChar = char;
|
|
493
|
+
}
|
|
494
|
+
else if (/^[A-Z]$/.test(char)) {
|
|
495
|
+
charType = 'UPPERCASE';
|
|
496
|
+
normalizedChar = char.toLowerCase();
|
|
497
|
+
}
|
|
498
|
+
else if (/^[0-9]$/.test(char)) {
|
|
499
|
+
charType = 'NUMBER';
|
|
500
|
+
normalizedChar = char;
|
|
501
|
+
}
|
|
502
|
+
else {
|
|
503
|
+
charType = 'OTHER';
|
|
504
|
+
normalizedChar = '';
|
|
505
|
+
}
|
|
506
|
+
if (!lastCharType) {
|
|
507
|
+
if (_isFirstLetterCapital) {
|
|
508
|
+
normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
else if (charType !== lastCharType &&
|
|
512
|
+
!(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
|
|
513
|
+
!(lastCharType === 'NUMBER') &&
|
|
514
|
+
!(charType === 'NUMBER')) {
|
|
515
|
+
normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
|
|
516
|
+
}
|
|
517
|
+
normalizedName += normalizedChar;
|
|
518
|
+
lastCharType = charType;
|
|
519
|
+
}
|
|
520
|
+
return normalizedName;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* TODO: [🌺] Use some intermediate util splitWords
|
|
524
|
+
*/
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Removes emojis from a string and fix whitespaces
|
|
528
|
+
*
|
|
529
|
+
* @param text with emojis
|
|
530
|
+
* @returns text without emojis
|
|
531
|
+
* @public exported from `@promptbook/utils`
|
|
532
|
+
*/
|
|
533
|
+
function removeEmojis(text) {
|
|
534
|
+
// Replace emojis (and also ZWJ sequence) with hyphens
|
|
535
|
+
text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
|
|
536
|
+
text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
|
|
537
|
+
text = text.replace(/(\p{Extended_Pictographic})(\u{200D}\p{Extended_Pictographic})*/gu, '$1');
|
|
538
|
+
text = text.replace(/\p{Extended_Pictographic}/gu, '');
|
|
226
539
|
return text;
|
|
227
540
|
}
|
|
228
541
|
|
|
@@ -451,474 +764,165 @@ for (let i = 0; i < defaultDiacriticsRemovalMap.length; i++) {
|
|
|
451
764
|
const letters = defaultDiacriticsRemovalMap[i].letters;
|
|
452
765
|
// tslint:disable-next-line: prefer-for-of
|
|
453
766
|
for (let j = 0; j < letters.length; j++) {
|
|
454
|
-
DIACRITIC_VARIANTS_LETTERS[letters[j]] = defaultDiacriticsRemovalMap[i].base;
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
// <- TODO: [🍓] Put to maker function to save execution time if not needed
|
|
458
|
-
/*
|
|
459
|
-
@see https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript
|
|
460
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
461
|
-
you may not use this file except in compliance with the License.
|
|
462
|
-
You may obtain a copy of the License at
|
|
463
|
-
|
|
464
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
465
|
-
|
|
466
|
-
Unless required by applicable law or agreed to in writing, software
|
|
467
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
468
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
469
|
-
See the License for the specific language governing permissions and
|
|
470
|
-
limitations under the License.
|
|
471
|
-
*/
|
|
472
|
-
|
|
473
|
-
/**
|
|
474
|
-
* @@@
|
|
475
|
-
*
|
|
476
|
-
* @param input @@@
|
|
477
|
-
* @returns @@@
|
|
478
|
-
* @public exported from `@promptbook/utils`
|
|
479
|
-
*/
|
|
480
|
-
function removeDiacritics(input) {
|
|
481
|
-
/*eslint no-control-regex: "off"*/
|
|
482
|
-
return input.replace(/[^\u0000-\u007E]/g, (a) => {
|
|
483
|
-
return DIACRITIC_VARIANTS_LETTERS[a] || a;
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
/**
|
|
487
|
-
* TODO: [Ж] Variant for cyrillic (and in general non-latin) letters
|
|
488
|
-
*/
|
|
489
|
-
|
|
490
|
-
/**
|
|
491
|
-
* @@@
|
|
492
|
-
*
|
|
493
|
-
* @param text @@@
|
|
494
|
-
* @returns @@@
|
|
495
|
-
* @example 'hello-world'
|
|
496
|
-
* @example 'i-love-promptbook'
|
|
497
|
-
* @public exported from `@promptbook/utils`
|
|
498
|
-
*/
|
|
499
|
-
function normalizeToKebabCase(text) {
|
|
500
|
-
text = removeDiacritics(text);
|
|
501
|
-
let charType;
|
|
502
|
-
let lastCharType = 'OTHER';
|
|
503
|
-
let normalizedName = '';
|
|
504
|
-
for (const char of text) {
|
|
505
|
-
let normalizedChar;
|
|
506
|
-
if (/^[a-z]$/.test(char)) {
|
|
507
|
-
charType = 'LOWERCASE';
|
|
508
|
-
normalizedChar = char;
|
|
509
|
-
}
|
|
510
|
-
else if (/^[A-Z]$/.test(char)) {
|
|
511
|
-
charType = 'UPPERCASE';
|
|
512
|
-
normalizedChar = char.toLowerCase();
|
|
513
|
-
}
|
|
514
|
-
else if (/^[0-9]$/.test(char)) {
|
|
515
|
-
charType = 'NUMBER';
|
|
516
|
-
normalizedChar = char;
|
|
517
|
-
}
|
|
518
|
-
else {
|
|
519
|
-
charType = 'OTHER';
|
|
520
|
-
normalizedChar = '-';
|
|
521
|
-
}
|
|
522
|
-
if (charType !== lastCharType &&
|
|
523
|
-
!(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
|
|
524
|
-
!(lastCharType === 'NUMBER') &&
|
|
525
|
-
!(charType === 'NUMBER')) {
|
|
526
|
-
normalizedName += '-';
|
|
527
|
-
}
|
|
528
|
-
normalizedName += normalizedChar;
|
|
529
|
-
lastCharType = charType;
|
|
530
|
-
}
|
|
531
|
-
normalizedName = normalizedName.split(/-+/g).join('-');
|
|
532
|
-
normalizedName = normalizedName.split(/-?\/-?/g).join('/');
|
|
533
|
-
normalizedName = normalizedName.replace(/^-/, '');
|
|
534
|
-
normalizedName = normalizedName.replace(/-$/, '');
|
|
535
|
-
return normalizedName;
|
|
536
|
-
}
|
|
537
|
-
/**
|
|
538
|
-
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
539
|
-
*/
|
|
540
|
-
|
|
541
|
-
/**
|
|
542
|
-
* This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
|
|
543
|
-
*
|
|
544
|
-
* @public exported from `@promptbook/core`
|
|
545
|
-
*/
|
|
546
|
-
class ParseError extends Error {
|
|
547
|
-
constructor(message) {
|
|
548
|
-
super(message);
|
|
549
|
-
this.name = 'ParseError';
|
|
550
|
-
Object.setPrototypeOf(this, ParseError.prototype);
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
/**
|
|
554
|
-
* TODO: Maybe split `ParseError` and `ApplyError`
|
|
555
|
-
*/
|
|
556
|
-
|
|
557
|
-
/**
|
|
558
|
-
* Generates random token
|
|
559
|
-
*
|
|
560
|
-
* Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
|
|
561
|
-
*
|
|
562
|
-
* @private internal helper function
|
|
563
|
-
* @returns secure random token
|
|
564
|
-
*/
|
|
565
|
-
function $randomToken(randomness) {
|
|
566
|
-
return randomBytes(randomness).toString('hex');
|
|
567
|
-
}
|
|
568
|
-
/**
|
|
569
|
-
* TODO: Maybe use nanoid instead https://github.com/ai/nanoid
|
|
570
|
-
*/
|
|
571
|
-
|
|
572
|
-
/**
|
|
573
|
-
* This error indicates errors during the execution of the pipeline
|
|
574
|
-
*
|
|
575
|
-
* @public exported from `@promptbook/core`
|
|
576
|
-
*/
|
|
577
|
-
class PipelineExecutionError extends Error {
|
|
578
|
-
constructor(message) {
|
|
579
|
-
// Added id parameter
|
|
580
|
-
super(message);
|
|
581
|
-
this.name = 'PipelineExecutionError';
|
|
582
|
-
// TODO: [🐙] DRY - Maybe $randomId
|
|
583
|
-
this.id = `error-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid simmilar char conflicts */)}`;
|
|
584
|
-
Object.setPrototypeOf(this, PipelineExecutionError.prototype);
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
/**
|
|
588
|
-
* TODO: [🧠][🌂] Add id to all errors
|
|
589
|
-
*/
|
|
590
|
-
|
|
591
|
-
/**
|
|
592
|
-
* This error type indicates that somewhere in the code non-Error object was thrown and it was wrapped into the `WrappedError`
|
|
593
|
-
*
|
|
594
|
-
* @public exported from `@promptbook/core`
|
|
595
|
-
*/
|
|
596
|
-
class WrappedError extends Error {
|
|
597
|
-
constructor(whatWasThrown) {
|
|
598
|
-
const tag = `[🤮]`;
|
|
599
|
-
console.error(tag, whatWasThrown);
|
|
600
|
-
super(spaceTrim$1(`
|
|
601
|
-
Non-Error object was thrown
|
|
602
|
-
|
|
603
|
-
Note: Look for ${tag} in the console for more details
|
|
604
|
-
Please report issue on ${ADMIN_EMAIL}
|
|
605
|
-
`));
|
|
606
|
-
this.name = 'WrappedError';
|
|
607
|
-
Object.setPrototypeOf(this, WrappedError.prototype);
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
/**
|
|
612
|
-
* Index of all javascript errors
|
|
613
|
-
*
|
|
614
|
-
* @private for internal usage
|
|
615
|
-
*/
|
|
616
|
-
({
|
|
617
|
-
Error,
|
|
618
|
-
EvalError,
|
|
619
|
-
RangeError,
|
|
620
|
-
ReferenceError,
|
|
621
|
-
SyntaxError,
|
|
622
|
-
TypeError,
|
|
623
|
-
URIError,
|
|
624
|
-
AggregateError,
|
|
625
|
-
/*
|
|
626
|
-
Note: Not widely supported
|
|
627
|
-
> InternalError,
|
|
628
|
-
> ModuleError,
|
|
629
|
-
> HeapError,
|
|
630
|
-
> WebAssemblyCompileError,
|
|
631
|
-
> WebAssemblyRuntimeError,
|
|
632
|
-
*/
|
|
633
|
-
});
|
|
634
|
-
/**
|
|
635
|
-
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
636
|
-
*/
|
|
637
|
-
|
|
638
|
-
/**
|
|
639
|
-
* Helper used in catch blocks to assert that the error is an instance of `Error`
|
|
640
|
-
*
|
|
641
|
-
* @param whatWasThrown Any object that was thrown
|
|
642
|
-
* @returns Nothing if the error is an instance of `Error`
|
|
643
|
-
* @throws `WrappedError` or `UnexpectedError` if the error is not standard
|
|
644
|
-
*
|
|
645
|
-
* @private within the repository
|
|
646
|
-
*/
|
|
647
|
-
function assertsError(whatWasThrown) {
|
|
648
|
-
// Case 1: Handle error which was rethrown as `WrappedError`
|
|
649
|
-
if (whatWasThrown instanceof WrappedError) {
|
|
650
|
-
const wrappedError = whatWasThrown;
|
|
651
|
-
throw wrappedError;
|
|
652
|
-
}
|
|
653
|
-
// Case 2: Handle unexpected errors
|
|
654
|
-
if (whatWasThrown instanceof UnexpectedError) {
|
|
655
|
-
const unexpectedError = whatWasThrown;
|
|
656
|
-
throw unexpectedError;
|
|
657
|
-
}
|
|
658
|
-
// Case 3: Handle standard errors - keep them up to consumer
|
|
659
|
-
if (whatWasThrown instanceof Error) {
|
|
660
|
-
return;
|
|
661
|
-
}
|
|
662
|
-
// Case 4: Handle non-standard errors - wrap them into `WrappedError` and throw
|
|
663
|
-
throw new WrappedError(whatWasThrown);
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
/**
|
|
667
|
-
* Orders JSON object by keys
|
|
668
|
-
*
|
|
669
|
-
* @returns The same type of object as the input re-ordered
|
|
670
|
-
* @public exported from `@promptbook/utils`
|
|
671
|
-
*/
|
|
672
|
-
function orderJson(options) {
|
|
673
|
-
const { value, order } = options;
|
|
674
|
-
const orderedValue = {
|
|
675
|
-
...(order === undefined ? {} : Object.fromEntries(order.map((key) => [key, undefined]))),
|
|
676
|
-
...value,
|
|
677
|
-
};
|
|
678
|
-
return orderedValue;
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
/**
|
|
682
|
-
* Freezes the given object and all its nested objects recursively
|
|
683
|
-
*
|
|
684
|
-
* Note: `$` is used to indicate that this function is not a pure function - it mutates given object
|
|
685
|
-
* Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
|
|
686
|
-
*
|
|
687
|
-
* @returns The same object as the input, but deeply frozen
|
|
688
|
-
* @public exported from `@promptbook/utils`
|
|
689
|
-
*/
|
|
690
|
-
function $deepFreeze(objectValue) {
|
|
691
|
-
if (Array.isArray(objectValue)) {
|
|
692
|
-
return Object.freeze(objectValue.map((item) => $deepFreeze(item)));
|
|
693
|
-
}
|
|
694
|
-
const propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
695
|
-
for (const propertyName of propertyNames) {
|
|
696
|
-
const value = objectValue[propertyName];
|
|
697
|
-
if (value && typeof value === 'object') {
|
|
698
|
-
$deepFreeze(value);
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
Object.freeze(objectValue);
|
|
702
|
-
return objectValue;
|
|
703
|
-
}
|
|
704
|
-
/**
|
|
705
|
-
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
706
|
-
*/
|
|
707
|
-
|
|
708
|
-
/**
|
|
709
|
-
* Checks if the value is [🚉] serializable as JSON
|
|
710
|
-
* If not, throws an UnexpectedError with a rich error message and tracking
|
|
711
|
-
*
|
|
712
|
-
* - Almost all primitives are serializable BUT:
|
|
713
|
-
* - `undefined` is not serializable
|
|
714
|
-
* - `NaN` is not serializable
|
|
715
|
-
* - Objects and arrays are serializable if all their properties are serializable
|
|
716
|
-
* - Functions are not serializable
|
|
717
|
-
* - Circular references are not serializable
|
|
718
|
-
* - `Date` objects are not serializable
|
|
719
|
-
* - `Map` and `Set` objects are not serializable
|
|
720
|
-
* - `RegExp` objects are not serializable
|
|
721
|
-
* - `Error` objects are not serializable
|
|
722
|
-
* - `Symbol` objects are not serializable
|
|
723
|
-
* - And much more...
|
|
724
|
-
*
|
|
725
|
-
* @throws UnexpectedError if the value is not serializable as JSON
|
|
726
|
-
* @public exported from `@promptbook/utils`
|
|
727
|
-
*/
|
|
728
|
-
function checkSerializableAsJson(options) {
|
|
729
|
-
const { value, name, message } = options;
|
|
730
|
-
if (value === undefined) {
|
|
731
|
-
throw new UnexpectedError(`${name} is undefined`);
|
|
732
|
-
}
|
|
733
|
-
else if (value === null) {
|
|
734
|
-
return;
|
|
735
|
-
}
|
|
736
|
-
else if (typeof value === 'boolean') {
|
|
737
|
-
return;
|
|
738
|
-
}
|
|
739
|
-
else if (typeof value === 'number' && !isNaN(value)) {
|
|
740
|
-
return;
|
|
741
|
-
}
|
|
742
|
-
else if (typeof value === 'string') {
|
|
743
|
-
return;
|
|
744
|
-
}
|
|
745
|
-
else if (typeof value === 'symbol') {
|
|
746
|
-
throw new UnexpectedError(`${name} is symbol`);
|
|
747
|
-
}
|
|
748
|
-
else if (typeof value === 'function') {
|
|
749
|
-
throw new UnexpectedError(`${name} is function`);
|
|
750
|
-
}
|
|
751
|
-
else if (typeof value === 'object' && Array.isArray(value)) {
|
|
752
|
-
for (let i = 0; i < value.length; i++) {
|
|
753
|
-
checkSerializableAsJson({ name: `${name}[${i}]`, value: value[i], message });
|
|
754
|
-
}
|
|
767
|
+
DIACRITIC_VARIANTS_LETTERS[letters[j]] = defaultDiacriticsRemovalMap[i].base;
|
|
755
768
|
}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
769
|
+
}
|
|
770
|
+
// <- TODO: [🍓] Put to maker function to save execution time if not needed
|
|
771
|
+
/*
|
|
772
|
+
@see https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript
|
|
773
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
774
|
+
you may not use this file except in compliance with the License.
|
|
775
|
+
You may obtain a copy of the License at
|
|
762
776
|
|
|
763
|
-
|
|
764
|
-
${block(message || '(nothing)')}
|
|
765
|
-
`));
|
|
766
|
-
}
|
|
767
|
-
else if (value instanceof Map) {
|
|
768
|
-
throw new UnexpectedError(`${name} is Map`);
|
|
769
|
-
}
|
|
770
|
-
else if (value instanceof Set) {
|
|
771
|
-
throw new UnexpectedError(`${name} is Set`);
|
|
772
|
-
}
|
|
773
|
-
else if (value instanceof RegExp) {
|
|
774
|
-
throw new UnexpectedError(`${name} is RegExp`);
|
|
775
|
-
}
|
|
776
|
-
else if (value instanceof Error) {
|
|
777
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
778
|
-
\`${name}\` is unserialized Error
|
|
777
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
779
778
|
|
|
780
|
-
|
|
779
|
+
Unless required by applicable law or agreed to in writing, software
|
|
780
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
781
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
782
|
+
See the License for the specific language governing permissions and
|
|
783
|
+
limitations under the License.
|
|
784
|
+
*/
|
|
781
785
|
|
|
782
|
-
|
|
783
|
-
|
|
786
|
+
/**
|
|
787
|
+
* Removes diacritic marks (accents) from characters in a string.
|
|
788
|
+
*
|
|
789
|
+
* @param input The string containing diacritics to be normalized.
|
|
790
|
+
* @returns The string with diacritics removed or normalized.
|
|
791
|
+
* @public exported from `@promptbook/utils`
|
|
792
|
+
*/
|
|
793
|
+
function removeDiacritics(input) {
|
|
794
|
+
/*eslint no-control-regex: "off"*/
|
|
795
|
+
return input.replace(/[^\u0000-\u007E]/g, (a) => {
|
|
796
|
+
return DIACRITIC_VARIANTS_LETTERS[a] || a;
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* TODO: [Ж] Variant for cyrillic (and in general non-latin) letters
|
|
801
|
+
*/
|
|
784
802
|
|
|
785
|
-
|
|
803
|
+
/**
|
|
804
|
+
* Converts a given text to kebab-case format.
|
|
805
|
+
*
|
|
806
|
+
* @param text The text to be converted.
|
|
807
|
+
* @returns The kebab-case formatted string.
|
|
808
|
+
* @example 'hello-world'
|
|
809
|
+
* @example 'i-love-promptbook'
|
|
810
|
+
* @public exported from `@promptbook/utils`
|
|
811
|
+
*/
|
|
812
|
+
function normalizeToKebabCase(text) {
|
|
813
|
+
text = removeDiacritics(text);
|
|
814
|
+
let charType;
|
|
815
|
+
let lastCharType = 'OTHER';
|
|
816
|
+
let normalizedName = '';
|
|
817
|
+
for (const char of text) {
|
|
818
|
+
let normalizedChar;
|
|
819
|
+
if (/^[a-z]$/.test(char)) {
|
|
820
|
+
charType = 'LOWERCASE';
|
|
821
|
+
normalizedChar = char;
|
|
822
|
+
}
|
|
823
|
+
else if (/^[A-Z]$/.test(char)) {
|
|
824
|
+
charType = 'UPPERCASE';
|
|
825
|
+
normalizedChar = char.toLowerCase();
|
|
826
|
+
}
|
|
827
|
+
else if (/^[0-9]$/.test(char)) {
|
|
828
|
+
charType = 'NUMBER';
|
|
829
|
+
normalizedChar = char;
|
|
786
830
|
}
|
|
787
831
|
else {
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
// Note: undefined in object is serializable - it is just omited
|
|
791
|
-
continue;
|
|
792
|
-
}
|
|
793
|
-
checkSerializableAsJson({ name: `${name}.${subName}`, value: subValue, message });
|
|
794
|
-
}
|
|
795
|
-
try {
|
|
796
|
-
JSON.stringify(value); // <- TODO: [0]
|
|
797
|
-
}
|
|
798
|
-
catch (error) {
|
|
799
|
-
assertsError(error);
|
|
800
|
-
throw new UnexpectedError(spaceTrim((block) => `
|
|
801
|
-
\`${name}\` is not serializable
|
|
802
|
-
|
|
803
|
-
${block(error.stack || error.message)}
|
|
804
|
-
|
|
805
|
-
Additional message for \`${name}\`:
|
|
806
|
-
${block(message || '(nothing)')}
|
|
807
|
-
`));
|
|
808
|
-
}
|
|
809
|
-
/*
|
|
810
|
-
TODO: [0] Is there some more elegant way to check circular references?
|
|
811
|
-
const seen = new Set();
|
|
812
|
-
const stack = [{ value }];
|
|
813
|
-
while (stack.length > 0) {
|
|
814
|
-
const { value } = stack.pop()!;
|
|
815
|
-
if (typeof value === 'object' && value !== null) {
|
|
816
|
-
if (seen.has(value)) {
|
|
817
|
-
throw new UnexpectedError(`${name} has circular reference`);
|
|
818
|
-
}
|
|
819
|
-
seen.add(value);
|
|
820
|
-
if (Array.isArray(value)) {
|
|
821
|
-
stack.push(...value.map((value) => ({ value })));
|
|
822
|
-
} else {
|
|
823
|
-
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
*/
|
|
828
|
-
return;
|
|
832
|
+
charType = 'OTHER';
|
|
833
|
+
normalizedChar = '-';
|
|
829
834
|
}
|
|
835
|
+
if (charType !== lastCharType &&
|
|
836
|
+
!(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
|
|
837
|
+
!(lastCharType === 'NUMBER') &&
|
|
838
|
+
!(charType === 'NUMBER')) {
|
|
839
|
+
normalizedName += '-';
|
|
840
|
+
}
|
|
841
|
+
normalizedName += normalizedChar;
|
|
842
|
+
lastCharType = charType;
|
|
830
843
|
}
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
${block(message || '(nothing)')}
|
|
837
|
-
`));
|
|
838
|
-
}
|
|
844
|
+
normalizedName = normalizedName.split(/-+/g).join('-');
|
|
845
|
+
normalizedName = normalizedName.split(/-?\/-?/g).join('/');
|
|
846
|
+
normalizedName = normalizedName.replace(/^-/, '');
|
|
847
|
+
normalizedName = normalizedName.replace(/-$/, '');
|
|
848
|
+
return normalizedName;
|
|
839
849
|
}
|
|
840
850
|
/**
|
|
841
|
-
*
|
|
842
|
-
* TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
843
|
-
* Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
851
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
844
852
|
*/
|
|
845
853
|
|
|
846
854
|
/**
|
|
847
|
-
*
|
|
855
|
+
* This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
|
|
848
856
|
*
|
|
849
|
-
* @public exported from `@promptbook/
|
|
857
|
+
* @public exported from `@promptbook/core`
|
|
850
858
|
*/
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
> const value = (objectValue as really_any)[propertyName];
|
|
858
|
-
> if (value && typeof value === 'object') {
|
|
859
|
-
> deepClone(value);
|
|
860
|
-
> }
|
|
861
|
-
> }
|
|
862
|
-
> return Object.assign({}, objectValue);
|
|
863
|
-
*/
|
|
859
|
+
class ParseError extends Error {
|
|
860
|
+
constructor(message) {
|
|
861
|
+
super(message);
|
|
862
|
+
this.name = 'ParseError';
|
|
863
|
+
Object.setPrototypeOf(this, ParseError.prototype);
|
|
864
|
+
}
|
|
864
865
|
}
|
|
865
866
|
/**
|
|
866
|
-
* TODO:
|
|
867
|
+
* TODO: Maybe split `ParseError` and `ApplyError`
|
|
867
868
|
*/
|
|
868
869
|
|
|
869
870
|
/**
|
|
870
|
-
*
|
|
871
|
-
*
|
|
872
|
-
* 1) Checks if the value is serializable as JSON
|
|
873
|
-
* 2) Makes a deep clone of the object
|
|
874
|
-
* 2) Orders the object properties
|
|
875
|
-
* 2) Deeply freezes the cloned object
|
|
871
|
+
* Generates random token
|
|
876
872
|
*
|
|
877
|
-
* Note: This function
|
|
873
|
+
* Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
|
|
878
874
|
*
|
|
879
|
-
* @
|
|
880
|
-
* @
|
|
875
|
+
* @private internal helper function
|
|
876
|
+
* @returns secure random token
|
|
881
877
|
*/
|
|
882
|
-
function
|
|
883
|
-
|
|
884
|
-
checkSerializableAsJson({ name, value, message });
|
|
885
|
-
const orderedValue =
|
|
886
|
-
// TODO: Fix error "Type instantiation is excessively deep and possibly infinite."
|
|
887
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
888
|
-
// @ts-ignore
|
|
889
|
-
order === undefined
|
|
890
|
-
? deepClone(value)
|
|
891
|
-
: orderJson({
|
|
892
|
-
value: value,
|
|
893
|
-
// <- Note: checkSerializableAsJson asserts that the value is serializable as JSON
|
|
894
|
-
order: order,
|
|
895
|
-
});
|
|
896
|
-
$deepFreeze(orderedValue);
|
|
897
|
-
return orderedValue;
|
|
878
|
+
function $randomToken(randomness) {
|
|
879
|
+
return randomBytes(randomness).toString('hex');
|
|
898
880
|
}
|
|
899
881
|
/**
|
|
900
|
-
* TODO:
|
|
882
|
+
* TODO: Maybe use nanoid instead https://github.com/ai/nanoid
|
|
901
883
|
*/
|
|
902
884
|
|
|
903
885
|
/**
|
|
904
|
-
*
|
|
886
|
+
* This error indicates errors during the execution of the pipeline
|
|
905
887
|
*
|
|
906
888
|
* @public exported from `@promptbook/core`
|
|
907
889
|
*/
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
'
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
890
|
+
class PipelineExecutionError extends Error {
|
|
891
|
+
constructor(message) {
|
|
892
|
+
// Added id parameter
|
|
893
|
+
super(message);
|
|
894
|
+
this.name = 'PipelineExecutionError';
|
|
895
|
+
// TODO: [🐙] DRY - Maybe $randomId
|
|
896
|
+
this.id = `error-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid simmilar char conflicts */)}`;
|
|
897
|
+
Object.setPrototypeOf(this, PipelineExecutionError.prototype);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* TODO: [🧠][🌂] Add id to all errors
|
|
902
|
+
*/
|
|
903
|
+
|
|
904
|
+
/**
|
|
905
|
+
* Index of all javascript errors
|
|
906
|
+
*
|
|
907
|
+
* @private for internal usage
|
|
908
|
+
*/
|
|
909
|
+
({
|
|
910
|
+
Error,
|
|
911
|
+
EvalError,
|
|
912
|
+
RangeError,
|
|
913
|
+
ReferenceError,
|
|
914
|
+
SyntaxError,
|
|
915
|
+
TypeError,
|
|
916
|
+
URIError,
|
|
917
|
+
AggregateError,
|
|
918
|
+
/*
|
|
919
|
+
Note: Not widely supported
|
|
920
|
+
> InternalError,
|
|
921
|
+
> ModuleError,
|
|
922
|
+
> HeapError,
|
|
923
|
+
> WebAssemblyCompileError,
|
|
924
|
+
> WebAssemblyRuntimeError,
|
|
925
|
+
*/
|
|
922
926
|
});
|
|
923
927
|
/**
|
|
924
928
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -1100,10 +1104,10 @@ function decapitalize(word) {
|
|
|
1100
1104
|
}
|
|
1101
1105
|
|
|
1102
1106
|
/**
|
|
1103
|
-
*
|
|
1107
|
+
* Normalizes a text string to SCREAMING_CASE (all uppercase with underscores).
|
|
1104
1108
|
*
|
|
1105
|
-
* @param text
|
|
1106
|
-
* @returns
|
|
1109
|
+
* @param text The text string to be converted to SCREAMING_CASE format.
|
|
1110
|
+
* @returns The normalized text in SCREAMING_CASE format.
|
|
1107
1111
|
* @example 'HELLO_WORLD'
|
|
1108
1112
|
* @example 'I_LOVE_PROMPTBOOK'
|
|
1109
1113
|
* @public exported from `@promptbook/utils`
|
|
@@ -1170,11 +1174,11 @@ function parseKeywordsFromString(input) {
|
|
|
1170
1174
|
}
|
|
1171
1175
|
|
|
1172
1176
|
/**
|
|
1173
|
-
*
|
|
1177
|
+
* Converts a name string into a URI-compatible format.
|
|
1174
1178
|
*
|
|
1175
|
-
* @param name
|
|
1176
|
-
* @returns
|
|
1177
|
-
* @example
|
|
1179
|
+
* @param name The string to be converted to a URI-compatible format.
|
|
1180
|
+
* @returns A URI-compatible string derived from the input name.
|
|
1181
|
+
* @example 'Hello World' -> 'hello-world'
|
|
1178
1182
|
* @public exported from `@promptbook/utils`
|
|
1179
1183
|
*/
|
|
1180
1184
|
function nameToUriPart(name) {
|
|
@@ -1188,11 +1192,11 @@ function nameToUriPart(name) {
|
|
|
1188
1192
|
}
|
|
1189
1193
|
|
|
1190
1194
|
/**
|
|
1191
|
-
*
|
|
1195
|
+
* Converts a given name into URI-compatible parts.
|
|
1192
1196
|
*
|
|
1193
|
-
* @param name
|
|
1194
|
-
* @returns
|
|
1195
|
-
* @example
|
|
1197
|
+
* @param name The name to be converted into URI parts.
|
|
1198
|
+
* @returns An array of URI-compatible parts derived from the name.
|
|
1199
|
+
* @example 'Example Name' -> ['example', 'name']
|
|
1196
1200
|
* @public exported from `@promptbook/utils`
|
|
1197
1201
|
*/
|
|
1198
1202
|
function nameToUriParts(name) {
|
|
@@ -1214,10 +1218,10 @@ function normalizeTo_PascalCase(text) {
|
|
|
1214
1218
|
}
|
|
1215
1219
|
|
|
1216
1220
|
/**
|
|
1217
|
-
*
|
|
1221
|
+
* Normalizes a text string to snake_case format.
|
|
1218
1222
|
*
|
|
1219
|
-
* @param text
|
|
1220
|
-
* @returns
|
|
1223
|
+
* @param text The text string to be converted to snake_case format.
|
|
1224
|
+
* @returns The normalized text in snake_case format.
|
|
1221
1225
|
* @example 'hello_world'
|
|
1222
1226
|
* @example 'i_love_promptbook'
|
|
1223
1227
|
* @public exported from `@promptbook/utils`
|
|
@@ -1755,7 +1759,11 @@ const trim = (str) => str.trim();
|
|
|
1755
1759
|
// TODO: DRY [🍯]
|
|
1756
1760
|
const reverse = (str) => str.split('').reverse().join('');
|
|
1757
1761
|
/**
|
|
1758
|
-
*
|
|
1762
|
+
* Collection of utility functions that can be used for post-processing model outputs.
|
|
1763
|
+
* These functions help transform, extract, or format the raw model responses.
|
|
1764
|
+
*
|
|
1765
|
+
* These utilities range from simple string manipulations to markdown processing
|
|
1766
|
+
* and formatting functions for specific types of output.
|
|
1759
1767
|
*
|
|
1760
1768
|
* @public exported from `@promptbook/javascript`
|
|
1761
1769
|
*/
|