@promptbook/utils 0.106.0-0 → 0.108.0-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/index.es.js +908 -128
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/_packages/components.index.d.ts +4 -0
- package/esm/typings/src/_packages/markdown-utils.index.d.ts +2 -0
- package/esm/typings/src/_packages/types.index.d.ts +15 -1
- package/esm/typings/src/_packages/utils.index.d.ts +2 -2
- package/esm/typings/src/book-components/BookEditor/BookEditor.d.ts +26 -2
- package/esm/typings/src/book-components/Chat/types/ChatMessage.d.ts +10 -2
- package/esm/typings/src/book-components/Chat/utils/getChatMessageTimingDisplay.d.ts +26 -0
- package/esm/typings/src/book-components/Chat/utils/{getToolCallChipletText.d.ts → getToolCallChipletInfo.d.ts} +8 -8
- package/esm/typings/src/types/ToolCall.d.ts +76 -1
- package/esm/typings/src/utils/linguistic-hash/LinguisticHashLanguage.d.ts +41 -0
- package/esm/typings/src/utils/linguistic-hash/linguisticHash.d.ts +37 -0
- package/esm/typings/src/utils/linguistic-hash/linguisticHashTypes.d.ts +19 -0
- package/esm/typings/src/utils/linguistic-hash/linguisticHashWords.cs.d.ts +10 -0
- package/esm/typings/src/utils/linguistic-hash/linguisticHashWords.en.d.ts +10 -0
- package/esm/typings/src/utils/markdown/humanizeAiTextSources.d.ts +13 -0
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +908 -128
- package/umd/index.umd.js.map +1 -1
- package/esm/typings/src/utils/misc/linguisticHash.d.ts +0 -9
- /package/esm/typings/src/utils/{misc → linguistic-hash}/linguisticHash.test.d.ts +0 -0
package/esm/index.es.js
CHANGED
|
@@ -18,7 +18,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
18
18
|
* @generated
|
|
19
19
|
* @see https://github.com/webgptorg/promptbook
|
|
20
20
|
*/
|
|
21
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.
|
|
21
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.108.0-0';
|
|
22
22
|
/**
|
|
23
23
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
24
24
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -2804,13 +2804,125 @@ function escapePromptParameterValue(value, options) {
|
|
|
2804
2804
|
return value.replace(pattern, '\\$&');
|
|
2805
2805
|
}
|
|
2806
2806
|
/**
|
|
2807
|
-
* Builds
|
|
2807
|
+
* Builds numeric parameter name used in prompt placeholders.
|
|
2808
2808
|
*
|
|
2809
2809
|
* @param index Zero-based parameter index.
|
|
2810
2810
|
*/
|
|
2811
|
-
function
|
|
2811
|
+
function buildNumericParameterName(index) {
|
|
2812
2812
|
return `${index + 1}`;
|
|
2813
2813
|
}
|
|
2814
|
+
/**
|
|
2815
|
+
* Builds alphabetic parameter name used in prompt placeholders.
|
|
2816
|
+
*
|
|
2817
|
+
* @param index Zero-based parameter index.
|
|
2818
|
+
*/
|
|
2819
|
+
function buildAlphabeticParameterName(index) {
|
|
2820
|
+
const alphabet = 'abcdefghijklmnopqrstuvwxyz';
|
|
2821
|
+
let result = '';
|
|
2822
|
+
let remaining = index;
|
|
2823
|
+
while (remaining >= 0) {
|
|
2824
|
+
result = alphabet[remaining % alphabet.length] + result;
|
|
2825
|
+
remaining = Math.floor(remaining / alphabet.length) - 1;
|
|
2826
|
+
}
|
|
2827
|
+
return result;
|
|
2828
|
+
}
|
|
2829
|
+
/**
|
|
2830
|
+
* Converts a positive integer into a Roman numeral string.
|
|
2831
|
+
*
|
|
2832
|
+
* @param value Positive integer value.
|
|
2833
|
+
*/
|
|
2834
|
+
function toRomanNumeral(value) {
|
|
2835
|
+
const romanTable = [
|
|
2836
|
+
{ symbol: 'M', value: 1000 },
|
|
2837
|
+
{ symbol: 'CM', value: 900 },
|
|
2838
|
+
{ symbol: 'D', value: 500 },
|
|
2839
|
+
{ symbol: 'CD', value: 400 },
|
|
2840
|
+
{ symbol: 'C', value: 100 },
|
|
2841
|
+
{ symbol: 'XC', value: 90 },
|
|
2842
|
+
{ symbol: 'L', value: 50 },
|
|
2843
|
+
{ symbol: 'XL', value: 40 },
|
|
2844
|
+
{ symbol: 'X', value: 10 },
|
|
2845
|
+
{ symbol: 'IX', value: 9 },
|
|
2846
|
+
{ symbol: 'V', value: 5 },
|
|
2847
|
+
{ symbol: 'IV', value: 4 },
|
|
2848
|
+
{ symbol: 'I', value: 1 },
|
|
2849
|
+
];
|
|
2850
|
+
let remaining = Math.max(1, Math.floor(value));
|
|
2851
|
+
let result = '';
|
|
2852
|
+
for (const entry of romanTable) {
|
|
2853
|
+
while (remaining >= entry.value) {
|
|
2854
|
+
result += entry.symbol;
|
|
2855
|
+
remaining -= entry.value;
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
return result;
|
|
2859
|
+
}
|
|
2860
|
+
/**
|
|
2861
|
+
* Builds Roman numeral parameter name used in prompt placeholders.
|
|
2862
|
+
*
|
|
2863
|
+
* @param index Zero-based parameter index.
|
|
2864
|
+
*/
|
|
2865
|
+
function buildRomanParameterName(index) {
|
|
2866
|
+
return toRomanNumeral(index + 1);
|
|
2867
|
+
}
|
|
2868
|
+
/**
|
|
2869
|
+
* Creates a parameter name builder that prefixes another builder.
|
|
2870
|
+
*
|
|
2871
|
+
* @param prefix Prefix to add.
|
|
2872
|
+
* @param builder Base builder to wrap.
|
|
2873
|
+
*/
|
|
2874
|
+
function buildPrefixedParameterName(prefix, builder) {
|
|
2875
|
+
return (index) => `${prefix}${builder(index)}`;
|
|
2876
|
+
}
|
|
2877
|
+
/**
|
|
2878
|
+
* Ordered list of strategies for parameter naming.
|
|
2879
|
+
*/
|
|
2880
|
+
const PARAMETER_NAME_STRATEGIES = [
|
|
2881
|
+
{ buildName: buildNumericParameterName },
|
|
2882
|
+
{ buildName: buildAlphabeticParameterName },
|
|
2883
|
+
{ buildName: buildRomanParameterName },
|
|
2884
|
+
{ buildName: buildPrefixedParameterName('p', buildNumericParameterName) },
|
|
2885
|
+
{ buildName: buildPrefixedParameterName('p', buildAlphabeticParameterName) },
|
|
2886
|
+
];
|
|
2887
|
+
/**
|
|
2888
|
+
* Collects bracketed tokens from parameter values to avoid placeholder collisions.
|
|
2889
|
+
*
|
|
2890
|
+
* @param values Parameter values to scan.
|
|
2891
|
+
*/
|
|
2892
|
+
function collectBracketedParameterTokens(values) {
|
|
2893
|
+
const tokens = new Set();
|
|
2894
|
+
for (const value of values) {
|
|
2895
|
+
const pattern = /{(\w+)}/g;
|
|
2896
|
+
let match;
|
|
2897
|
+
while ((match = pattern.exec(value)) !== null) {
|
|
2898
|
+
const token = match[1];
|
|
2899
|
+
if (token) {
|
|
2900
|
+
tokens.add(token);
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
return tokens;
|
|
2905
|
+
}
|
|
2906
|
+
/**
|
|
2907
|
+
* Builds parameter names used in prompt placeholders while avoiding collisions.
|
|
2908
|
+
*
|
|
2909
|
+
* @param values Parameter values to scan for conflicting tokens.
|
|
2910
|
+
*/
|
|
2911
|
+
function buildParameterNames(values) {
|
|
2912
|
+
const count = values.length;
|
|
2913
|
+
if (count === 0) {
|
|
2914
|
+
return [];
|
|
2915
|
+
}
|
|
2916
|
+
const conflicts = collectBracketedParameterTokens(values);
|
|
2917
|
+
for (const strategy of PARAMETER_NAME_STRATEGIES) {
|
|
2918
|
+
const names = Array.from({ length: count }, (_, index) => strategy.buildName(index));
|
|
2919
|
+
const hasConflict = names.some((name) => conflicts.has(name));
|
|
2920
|
+
if (!hasConflict) {
|
|
2921
|
+
return names;
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
return Array.from({ length: count }, (_, index) => `${REPLACING_NONCE}${index + 1}`);
|
|
2925
|
+
}
|
|
2814
2926
|
/**
|
|
2815
2927
|
* Formats the placeholder used in the prompt body for a parameter.
|
|
2816
2928
|
*
|
|
@@ -2865,26 +2977,40 @@ function prompt(strings, ...values) {
|
|
|
2865
2977
|
return new PromptString(spaceTrim$2(strings.join('')));
|
|
2866
2978
|
}
|
|
2867
2979
|
const stringsWithHiddenParameters = strings.map((stringsItem) => hideBrackets(stringsItem));
|
|
2868
|
-
const
|
|
2869
|
-
const name = buildParameterName(index);
|
|
2980
|
+
const parameterMetadata = values.map((value) => {
|
|
2870
2981
|
const isPrompt = isPromptString(value);
|
|
2871
2982
|
const stringValue = isPrompt ? value.toString() : valueToString(value);
|
|
2872
2983
|
const isInline = isPrompt ? true : shouldInlineParameterValue(stringValue);
|
|
2873
2984
|
const jsonValue = !isPrompt && !isInline ? normalizeJsonString(stringValue) : null;
|
|
2985
|
+
return { isPrompt, stringValue, isInline, jsonValue };
|
|
2986
|
+
});
|
|
2987
|
+
const parameterNames = buildParameterNames(parameterMetadata.map((entry) => entry.stringValue));
|
|
2988
|
+
const parameterEntries = parameterMetadata.map((entry, index) => {
|
|
2989
|
+
var _a;
|
|
2990
|
+
const name = (_a = parameterNames[index]) !== null && _a !== void 0 ? _a : buildNumericParameterName(index);
|
|
2874
2991
|
const promptMarker = `${REPLACING_NONCE}prompt-${index}`;
|
|
2875
2992
|
const parameterMarker = `${REPLACING_NONCE}parameter-${index}`;
|
|
2876
|
-
const templateValue = isPrompt
|
|
2993
|
+
const templateValue = entry.isPrompt
|
|
2877
2994
|
? promptMarker
|
|
2878
|
-
: isInline
|
|
2879
|
-
? escapePromptParameterValue(stringValue, { includeBraces: false })
|
|
2995
|
+
: entry.isInline
|
|
2996
|
+
? escapePromptParameterValue(entry.stringValue, { includeBraces: false })
|
|
2880
2997
|
: parameterMarker;
|
|
2881
|
-
return {
|
|
2998
|
+
return {
|
|
2999
|
+
name,
|
|
3000
|
+
stringValue: entry.stringValue,
|
|
3001
|
+
jsonValue: entry.jsonValue,
|
|
3002
|
+
isPrompt: entry.isPrompt,
|
|
3003
|
+
isInline: entry.isInline,
|
|
3004
|
+
promptMarker,
|
|
3005
|
+
parameterMarker,
|
|
3006
|
+
templateValue,
|
|
3007
|
+
};
|
|
2882
3008
|
});
|
|
2883
3009
|
const parameters = Object.fromEntries(parameterEntries.map((entry) => [entry.name, entry.templateValue]));
|
|
2884
|
-
const
|
|
3010
|
+
const parameterNamesOrdered = parameterEntries.map((entry) => entry.name);
|
|
2885
3011
|
// Combine strings and values
|
|
2886
3012
|
let pipelineString = stringsWithHiddenParameters.reduce((result, stringsItem, i) => {
|
|
2887
|
-
const parameterName =
|
|
3013
|
+
const parameterName = parameterNamesOrdered[i];
|
|
2888
3014
|
return parameterName === undefined
|
|
2889
3015
|
? `${result}${stringsItem}`
|
|
2890
3016
|
: `${result}${stringsItem}${formatParameterPlaceholder(parameterName)}`;
|
|
@@ -2897,7 +3023,7 @@ function prompt(strings, ...values) {
|
|
|
2897
3023
|
if (!(error instanceof PipelineExecutionError)) {
|
|
2898
3024
|
throw error;
|
|
2899
3025
|
}
|
|
2900
|
-
console.error({ pipelineString, parameters, parameterNames, error });
|
|
3026
|
+
console.error({ pipelineString, parameters, parameterNames: parameterNamesOrdered, error });
|
|
2901
3027
|
throw new UnexpectedError(spaceTrim$2((block) => `
|
|
2902
3028
|
Internal error in prompt template literal
|
|
2903
3029
|
|
|
@@ -2912,9 +3038,7 @@ function prompt(strings, ...values) {
|
|
|
2912
3038
|
continue;
|
|
2913
3039
|
}
|
|
2914
3040
|
if (!entry.isInline) {
|
|
2915
|
-
pipelineString = pipelineString
|
|
2916
|
-
.split(entry.parameterMarker)
|
|
2917
|
-
.join(formatParameterPlaceholder(entry.name));
|
|
3041
|
+
pipelineString = pipelineString.split(entry.parameterMarker).join(formatParameterPlaceholder(entry.name));
|
|
2918
3042
|
}
|
|
2919
3043
|
}
|
|
2920
3044
|
const structuredParameters = parameterEntries.filter((entry) => !entry.isPrompt && !entry.isInline);
|
|
@@ -3187,18 +3311,6 @@ const CountUtils = {
|
|
|
3187
3311
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
3188
3312
|
*/
|
|
3189
3313
|
|
|
3190
|
-
/**
|
|
3191
|
-
* Simple wrapper `new Date().toISOString()`
|
|
3192
|
-
*
|
|
3193
|
-
* Note: `$` is used to indicate that this function is not a pure function - it is not deterministic because it depends on the current time
|
|
3194
|
-
*
|
|
3195
|
-
* @returns string_date branded type
|
|
3196
|
-
* @public exported from `@promptbook/utils`
|
|
3197
|
-
*/
|
|
3198
|
-
function $getCurrentDate() {
|
|
3199
|
-
return new Date().toISOString();
|
|
3200
|
-
}
|
|
3201
|
-
|
|
3202
3314
|
/**
|
|
3203
3315
|
* Computes SHA-256 hash of the given object
|
|
3204
3316
|
*
|
|
@@ -3211,18 +3323,6 @@ function computeHash(value) {
|
|
|
3211
3323
|
* TODO: [🥬][🥬] Use this ACRY
|
|
3212
3324
|
*/
|
|
3213
3325
|
|
|
3214
|
-
/**
|
|
3215
|
-
* @public exported from `@promptbook/utils`
|
|
3216
|
-
*/
|
|
3217
|
-
function debounce(fn, delay) {
|
|
3218
|
-
let timeout = null;
|
|
3219
|
-
return (...args) => {
|
|
3220
|
-
if (timeout)
|
|
3221
|
-
clearTimeout(timeout);
|
|
3222
|
-
timeout = setTimeout(() => fn(...args), delay);
|
|
3223
|
-
};
|
|
3224
|
-
}
|
|
3225
|
-
|
|
3226
3326
|
/**
|
|
3227
3327
|
* Makes first letter of a string uppercase
|
|
3228
3328
|
*
|
|
@@ -3234,103 +3334,564 @@ function capitalize(word) {
|
|
|
3234
3334
|
return word.substring(0, 1).toUpperCase() + word.substring(1);
|
|
3235
3335
|
}
|
|
3236
3336
|
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
*
|
|
3240
|
-
*
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
'
|
|
3249
|
-
'
|
|
3250
|
-
'
|
|
3251
|
-
'
|
|
3252
|
-
'
|
|
3253
|
-
'
|
|
3254
|
-
'
|
|
3255
|
-
'
|
|
3256
|
-
'
|
|
3257
|
-
'
|
|
3258
|
-
'
|
|
3259
|
-
'
|
|
3337
|
+
// spell-checker: disable
|
|
3338
|
+
/**
|
|
3339
|
+
* @@@
|
|
3340
|
+
*
|
|
3341
|
+
* @private utility of `linguisticHash`
|
|
3342
|
+
*/
|
|
3343
|
+
const ADJECTIVES$1 = [
|
|
3344
|
+
'červený',
|
|
3345
|
+
'modrý',
|
|
3346
|
+
'zelený',
|
|
3347
|
+
'žlutý',
|
|
3348
|
+
'rychlý',
|
|
3349
|
+
'pomalý',
|
|
3350
|
+
'jasný',
|
|
3351
|
+
'temný',
|
|
3352
|
+
'veselý',
|
|
3353
|
+
'smutný',
|
|
3354
|
+
'statečný',
|
|
3355
|
+
'klidný',
|
|
3356
|
+
'chytrý',
|
|
3357
|
+
'bystrý',
|
|
3358
|
+
'dychtivý',
|
|
3359
|
+
'honosný',
|
|
3360
|
+
'velkolepý',
|
|
3361
|
+
'hravý',
|
|
3362
|
+
'laskavý',
|
|
3363
|
+
'šťastný',
|
|
3364
|
+
'hrdý',
|
|
3365
|
+
'pošetilý',
|
|
3366
|
+
'moudrý',
|
|
3367
|
+
'mladý',
|
|
3368
|
+
'starý',
|
|
3369
|
+
'veliký',
|
|
3370
|
+
'malý',
|
|
3371
|
+
'drobný',
|
|
3372
|
+
'obrovský',
|
|
3373
|
+
'krátký',
|
|
3374
|
+
'dlouhý',
|
|
3375
|
+
'blízký',
|
|
3376
|
+
'vzdálený',
|
|
3377
|
+
'vnitřní',
|
|
3378
|
+
'vnější',
|
|
3379
|
+
'trpělivý',
|
|
3380
|
+
'stálý',
|
|
3381
|
+
'ušlechtilý',
|
|
3382
|
+
'čistý',
|
|
3383
|
+
'špinavý',
|
|
3384
|
+
'čerstvý',
|
|
3385
|
+
'zvětralý',
|
|
3386
|
+
'ostrý',
|
|
3387
|
+
'tupý',
|
|
3388
|
+
'tlustý',
|
|
3389
|
+
'tenký',
|
|
3390
|
+
'široký',
|
|
3391
|
+
'úzký',
|
|
3392
|
+
'hluboký',
|
|
3393
|
+
'mělký',
|
|
3394
|
+
'mocný',
|
|
3395
|
+
'jemný',
|
|
3396
|
+
'divoký',
|
|
3397
|
+
'tichý',
|
|
3398
|
+
'hlučný',
|
|
3399
|
+
'pokojný',
|
|
3400
|
+
'rušný',
|
|
3401
|
+
'prázdný',
|
|
3402
|
+
'plný',
|
|
3403
|
+
'kulatý',
|
|
3404
|
+
'hranatý',
|
|
3405
|
+
'plochý',
|
|
3406
|
+
'křivý',
|
|
3407
|
+
'tvrdý',
|
|
3408
|
+
'měkký',
|
|
3409
|
+
'teplý',
|
|
3410
|
+
'chladný',
|
|
3411
|
+
'sladký',
|
|
3412
|
+
'kyselý',
|
|
3413
|
+
'hořký',
|
|
3414
|
+
'slaný',
|
|
3415
|
+
'silný',
|
|
3416
|
+
'slabý',
|
|
3417
|
+
'pevný',
|
|
3418
|
+
'pružný',
|
|
3419
|
+
'křehký',
|
|
3420
|
+
'houževnatý',
|
|
3421
|
+
'lesklý',
|
|
3422
|
+
'matný',
|
|
3423
|
+
'kluzký',
|
|
3424
|
+
'lepkavý',
|
|
3425
|
+
'svěží',
|
|
3426
|
+
'vybledlý',
|
|
3427
|
+
'mlhavý',
|
|
3428
|
+
'bouřlivý',
|
|
3429
|
+
'slunný',
|
|
3430
|
+
'větrný',
|
|
3431
|
+
'deštivý',
|
|
3432
|
+
'mrazivý',
|
|
3433
|
+
'zlatý',
|
|
3434
|
+
'stříbrný',
|
|
3435
|
+
'ledový',
|
|
3436
|
+
'žhavý',
|
|
3437
|
+
'prastarý',
|
|
3438
|
+
'moderní',
|
|
3439
|
+
'skrytý',
|
|
3440
|
+
'ztracený',
|
|
3441
|
+
'nalezený',
|
|
3442
|
+
'magický',
|
|
3443
|
+
'tajemný',
|
|
3444
|
+
'kosmický',
|
|
3445
|
+
'hvězdný',
|
|
3446
|
+
'měsíční',
|
|
3447
|
+
'sluneční',
|
|
3448
|
+
'mlžný',
|
|
3449
|
+
'ranní',
|
|
3450
|
+
'večerní',
|
|
3451
|
+
'noční',
|
|
3452
|
+
'denní',
|
|
3453
|
+
'osamělý',
|
|
3454
|
+
'společenský',
|
|
3455
|
+
'soukromý',
|
|
3456
|
+
'veřejný',
|
|
3457
|
+
'tajný',
|
|
3458
|
+
'slavný',
|
|
3459
|
+
'jistý',
|
|
3460
|
+
'neurčitý',
|
|
3461
|
+
'prostý',
|
|
3462
|
+
'snadný',
|
|
3463
|
+
'krotký',
|
|
3464
|
+
'mírný',
|
|
3465
|
+
'horký',
|
|
3466
|
+
'suchý',
|
|
3467
|
+
'mokrý',
|
|
3468
|
+
'vlhký',
|
|
3469
|
+
'promočený',
|
|
3470
|
+
'vyprahlý',
|
|
3471
|
+
'hladový',
|
|
3472
|
+
'žíznivý',
|
|
3473
|
+
'ospalý',
|
|
3474
|
+
'bdělý',
|
|
3475
|
+
'unavený',
|
|
3476
|
+
'líný',
|
|
3477
|
+
'neklidný',
|
|
3478
|
+
'nestálý',
|
|
3479
|
+
'odvážný',
|
|
3480
|
+
'bázlivý',
|
|
3481
|
+
'upřímný',
|
|
3482
|
+
'věrný',
|
|
3483
|
+
'pravý',
|
|
3484
|
+
'falešný',
|
|
3485
|
+
'spravedlivý',
|
|
3486
|
+
'jednoduchý',
|
|
3487
|
+
'složitý',
|
|
3488
|
+
'přirozený',
|
|
3489
|
+
'umělý',
|
|
3490
|
+
'živý',
|
|
3491
|
+
'mrtvý',
|
|
3492
|
+
'zvídavý',
|
|
3493
|
+
'zvláštní',
|
|
3494
|
+
'běžný',
|
|
3495
|
+
'vzácný',
|
|
3496
|
+
'jedinečný',
|
|
3497
|
+
'základní',
|
|
3498
|
+
'prvotní',
|
|
3499
|
+
'hbitý',
|
|
3260
3500
|
];
|
|
3261
|
-
const
|
|
3262
|
-
|
|
3263
|
-
'
|
|
3264
|
-
'
|
|
3265
|
-
'
|
|
3266
|
-
'
|
|
3267
|
-
'
|
|
3268
|
-
'
|
|
3269
|
-
'
|
|
3270
|
-
'
|
|
3271
|
-
'
|
|
3272
|
-
'
|
|
3273
|
-
'
|
|
3274
|
-
'
|
|
3275
|
-
'
|
|
3276
|
-
'
|
|
3501
|
+
const NOUNS$1 = [
|
|
3502
|
+
'jablko',
|
|
3503
|
+
'nebe',
|
|
3504
|
+
'strom',
|
|
3505
|
+
'liška',
|
|
3506
|
+
'kočka',
|
|
3507
|
+
'pták',
|
|
3508
|
+
'pes',
|
|
3509
|
+
'řeka',
|
|
3510
|
+
'hora',
|
|
3511
|
+
'les',
|
|
3512
|
+
'oceán',
|
|
3513
|
+
'hvězda',
|
|
3514
|
+
'měsíc',
|
|
3515
|
+
'slunce',
|
|
3516
|
+
'mrak',
|
|
3517
|
+
'květ',
|
|
3518
|
+
'list',
|
|
3519
|
+
'kámen',
|
|
3520
|
+
'vítr',
|
|
3521
|
+
'déšť',
|
|
3522
|
+
'oheň',
|
|
3523
|
+
'led',
|
|
3524
|
+
'kniha',
|
|
3525
|
+
'sen',
|
|
3526
|
+
'píseň',
|
|
3527
|
+
'cesta',
|
|
3528
|
+
'brána',
|
|
3529
|
+
'klíč',
|
|
3530
|
+
'lampa',
|
|
3531
|
+
'mapa',
|
|
3532
|
+
'dům',
|
|
3533
|
+
'město',
|
|
3534
|
+
'most',
|
|
3535
|
+
'pole',
|
|
3536
|
+
'zahrada',
|
|
3537
|
+
'jezero',
|
|
3538
|
+
'pláž',
|
|
3539
|
+
'ostrov',
|
|
3540
|
+
'údolí',
|
|
3541
|
+
'poušť',
|
|
3542
|
+
'svět',
|
|
3543
|
+
'duch',
|
|
3544
|
+
'srdce',
|
|
3545
|
+
'mysl',
|
|
3546
|
+
'duše',
|
|
3547
|
+
'život',
|
|
3548
|
+
'čas',
|
|
3549
|
+
'prostor',
|
|
3550
|
+
'světlo',
|
|
3551
|
+
'stín',
|
|
3552
|
+
'zvuk',
|
|
3553
|
+
'hudba',
|
|
3554
|
+
'hlas',
|
|
3555
|
+
'slovo',
|
|
3556
|
+
'stránka',
|
|
3557
|
+
'příběh',
|
|
3558
|
+
'perla',
|
|
3559
|
+
'zlato',
|
|
3560
|
+
'stříbro',
|
|
3561
|
+
'krystal',
|
|
3562
|
+
'diamant',
|
|
3563
|
+
'smaragd',
|
|
3564
|
+
'rubín',
|
|
3565
|
+
'stezka',
|
|
3566
|
+
'vrchol',
|
|
3567
|
+
'břeh',
|
|
3568
|
+
'vlna',
|
|
3569
|
+
'příliv',
|
|
3570
|
+
'plamen',
|
|
3571
|
+
'jiskra',
|
|
3572
|
+
'paprsek',
|
|
3573
|
+
'semínko',
|
|
3574
|
+
'kořen',
|
|
3575
|
+
'větev',
|
|
3576
|
+
'pupen',
|
|
3577
|
+
'trn',
|
|
3578
|
+
'kůra',
|
|
3579
|
+
'skořápka',
|
|
3580
|
+
'pírko',
|
|
3581
|
+
'křídlo',
|
|
3582
|
+
'dráp',
|
|
3583
|
+
'tlapa',
|
|
3584
|
+
'hnízdo',
|
|
3585
|
+
'jeskyně',
|
|
3586
|
+
'hájek',
|
|
3587
|
+
'věž',
|
|
3588
|
+
'hrad',
|
|
3589
|
+
'koruna',
|
|
3590
|
+
'meč',
|
|
3591
|
+
'štít',
|
|
3592
|
+
'mince',
|
|
3593
|
+
'drahokam',
|
|
3594
|
+
'prsten',
|
|
3595
|
+
'zvonek',
|
|
3596
|
+
'hodiny',
|
|
3597
|
+
'kompas',
|
|
3598
|
+
'kotva',
|
|
3599
|
+
'pochodeň',
|
|
3600
|
+
'flétna',
|
|
3601
|
+
'harfa',
|
|
3602
|
+
'buben',
|
|
3603
|
+
'čočka',
|
|
3604
|
+
'sklo',
|
|
3605
|
+
'písek',
|
|
3606
|
+
'prach',
|
|
3607
|
+
'mlha',
|
|
3608
|
+
'rosa',
|
|
3609
|
+
'svítání',
|
|
3610
|
+
'soumrak',
|
|
3611
|
+
'noc',
|
|
3612
|
+
'den',
|
|
3613
|
+
'rok',
|
|
3614
|
+
'věk',
|
|
3615
|
+
'blesk',
|
|
3616
|
+
'kapka',
|
|
3617
|
+
'bouře',
|
|
3618
|
+
'sníh',
|
|
3619
|
+
'kroupa',
|
|
3620
|
+
'kouř',
|
|
3621
|
+
'pára',
|
|
3622
|
+
'plyn',
|
|
3623
|
+
'kov',
|
|
3624
|
+
'skála',
|
|
3625
|
+
'hlína',
|
|
3626
|
+
'sůl',
|
|
3627
|
+
'cukr',
|
|
3628
|
+
'dřevo',
|
|
3629
|
+
'kost',
|
|
3630
|
+
'kůže',
|
|
3631
|
+
'tělo',
|
|
3632
|
+
'krev',
|
|
3633
|
+
'buňka',
|
|
3634
|
+
'atom',
|
|
3635
|
+
'tep',
|
|
3636
|
+
'dech',
|
|
3637
|
+
'vzdech',
|
|
3638
|
+
'jméno',
|
|
3639
|
+
'ozvěna',
|
|
3640
|
+
'obraz',
|
|
3641
|
+
'vize',
|
|
3642
|
+
'myšlenka',
|
|
3643
|
+
'nápad',
|
|
3644
|
+
'plán',
|
|
3645
|
+
'cíl',
|
|
3646
|
+
'přání',
|
|
3647
|
+
'naděje',
|
|
3648
|
+
'strach',
|
|
3649
|
+
'radost',
|
|
3650
|
+
'láska',
|
|
3651
|
+
'nenávist',
|
|
3652
|
+
'vůle',
|
|
3653
|
+
'síla',
|
|
3654
|
+
'energie',
|
|
3655
|
+
'pohyb',
|
|
3656
|
+
'rychlost',
|
|
3657
|
+
'místo',
|
|
3658
|
+
'bod',
|
|
3659
|
+
'linie',
|
|
3660
|
+
'tvar',
|
|
3661
|
+
'forma',
|
|
3662
|
+
'velikost',
|
|
3663
|
+
'hmota',
|
|
3664
|
+
'váha',
|
|
3665
|
+
'teplo',
|
|
3666
|
+
'chlad',
|
|
3667
|
+
'barva',
|
|
3668
|
+
'tón',
|
|
3669
|
+
'rytmus',
|
|
3670
|
+
'nálada',
|
|
3671
|
+
'stav',
|
|
3672
|
+
'krok',
|
|
3673
|
+
'pád',
|
|
3674
|
+
'skok',
|
|
3675
|
+
'běh',
|
|
3676
|
+
'let',
|
|
3677
|
+
'klid',
|
|
3678
|
+
'úkol',
|
|
3679
|
+
'práce',
|
|
3680
|
+
'hra',
|
|
3681
|
+
'sport',
|
|
3682
|
+
'umění',
|
|
3683
|
+
'řemeslo',
|
|
3684
|
+
'nástroj',
|
|
3685
|
+
'loď',
|
|
3686
|
+
'člun',
|
|
3687
|
+
'auto',
|
|
3688
|
+
'kolo',
|
|
3689
|
+
'vlak',
|
|
3690
|
+
'letadlo',
|
|
3691
|
+
'uzel',
|
|
3692
|
+
'síť',
|
|
3693
|
+
'krabice',
|
|
3694
|
+
'taška',
|
|
3695
|
+
'dóza',
|
|
3696
|
+
'hrnek',
|
|
3697
|
+
'miska',
|
|
3698
|
+
'talíř',
|
|
3699
|
+
'lžíce',
|
|
3700
|
+
'vidlička',
|
|
3701
|
+
'nůž',
|
|
3702
|
+
'pánev',
|
|
3703
|
+
'hrnec',
|
|
3704
|
+
'postel',
|
|
3705
|
+
'stůl',
|
|
3706
|
+
'židle',
|
|
3707
|
+
'dveře',
|
|
3708
|
+
'stěna',
|
|
3709
|
+
'střecha',
|
|
3710
|
+
'podlaha',
|
|
3711
|
+
'okno',
|
|
3712
|
+
'chodba',
|
|
3277
3713
|
];
|
|
3278
|
-
const
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3714
|
+
const VERBS$1 = [
|
|
3715
|
+
'skáče',
|
|
3716
|
+
'tančí',
|
|
3717
|
+
'letí',
|
|
3718
|
+
'běží',
|
|
3719
|
+
'zpívá',
|
|
3720
|
+
'svítí',
|
|
3721
|
+
'roste',
|
|
3722
|
+
'plyne',
|
|
3723
|
+
'padá',
|
|
3724
|
+
'stoupá',
|
|
3725
|
+
'spí',
|
|
3726
|
+
'kráčí',
|
|
3727
|
+
'mluví',
|
|
3728
|
+
'myslí',
|
|
3729
|
+
'sní',
|
|
3730
|
+
'hledá',
|
|
3731
|
+
'nachází',
|
|
3732
|
+
'dává',
|
|
3733
|
+
'bere',
|
|
3734
|
+
'tvoří',
|
|
3735
|
+
'hoří',
|
|
3736
|
+
'mrzne',
|
|
3737
|
+
'taje',
|
|
3738
|
+
'dýchá',
|
|
3739
|
+
'pulzuje',
|
|
3740
|
+
'bije',
|
|
3741
|
+
'žije',
|
|
3742
|
+
'učí',
|
|
3743
|
+
'ví',
|
|
3744
|
+
'skrývá',
|
|
3745
|
+
'ukazuje',
|
|
3746
|
+
'láme',
|
|
3747
|
+
'opravuje',
|
|
3748
|
+
'ztrácí',
|
|
3749
|
+
'nalézá',
|
|
3750
|
+
'začíná',
|
|
3751
|
+
'končí',
|
|
3752
|
+
'plave',
|
|
3753
|
+
'pluje',
|
|
3754
|
+
'klouže',
|
|
3755
|
+
'točí',
|
|
3756
|
+
'mění',
|
|
3757
|
+
'bledne',
|
|
3758
|
+
'mizí',
|
|
3759
|
+
'rodí',
|
|
3760
|
+
'hučí',
|
|
3761
|
+
'pláče',
|
|
3762
|
+
'závodí',
|
|
3763
|
+
'plíží',
|
|
3764
|
+
'sleduje',
|
|
3765
|
+
'slyší',
|
|
3766
|
+
'cítí',
|
|
3767
|
+
'touží',
|
|
3768
|
+
'doufá',
|
|
3769
|
+
'miluje',
|
|
3770
|
+
'bloudí',
|
|
3771
|
+
'putuje',
|
|
3772
|
+
'cestuje',
|
|
3773
|
+
'překračuje',
|
|
3774
|
+
'potkává',
|
|
3775
|
+
'drží',
|
|
3776
|
+
'sdílí',
|
|
3777
|
+
'jiskří',
|
|
3778
|
+
'plápolá',
|
|
3779
|
+
'léčí',
|
|
3780
|
+
'řeší',
|
|
3781
|
+
'otevírá',
|
|
3782
|
+
'zavírá',
|
|
3783
|
+
'zvedá',
|
|
3784
|
+
'táhne',
|
|
3785
|
+
'tlačí',
|
|
3786
|
+
'hází',
|
|
3787
|
+
'chytá',
|
|
3788
|
+
'dělá',
|
|
3789
|
+
'vidí',
|
|
3790
|
+
'chutná',
|
|
3791
|
+
'voní',
|
|
3792
|
+
'spěchá',
|
|
3793
|
+
'zastaví',
|
|
3794
|
+
'jde',
|
|
3795
|
+
'přichází',
|
|
3796
|
+
'odchází',
|
|
3797
|
+
'jedná',
|
|
3798
|
+
'existuje',
|
|
3799
|
+
'zmenšuje',
|
|
3800
|
+
'rozšiřuje',
|
|
3801
|
+
'zužuje',
|
|
3802
|
+
'hřeje',
|
|
3803
|
+
'chladí',
|
|
3804
|
+
'suší',
|
|
3805
|
+
'máčí',
|
|
3806
|
+
'plní',
|
|
3807
|
+
'vyprazdňuje',
|
|
3808
|
+
'pouští',
|
|
3809
|
+
'získává',
|
|
3810
|
+
'vítězí',
|
|
3811
|
+
'selhává',
|
|
3812
|
+
'zkouší',
|
|
3813
|
+
'používá',
|
|
3814
|
+
'dostává',
|
|
3815
|
+
'měří',
|
|
3816
|
+
'stojí',
|
|
3817
|
+
'dosahuje',
|
|
3818
|
+
'míjí',
|
|
3819
|
+
'udeří',
|
|
3820
|
+
'vede',
|
|
3821
|
+
'následuje',
|
|
3822
|
+
'pomáhá',
|
|
3823
|
+
'slouží',
|
|
3824
|
+
'trénuje',
|
|
3825
|
+
'kóduje',
|
|
3826
|
+
'píše',
|
|
3827
|
+
'čte',
|
|
3828
|
+
'kreslí',
|
|
3829
|
+
'maluje',
|
|
3830
|
+
'tvaruje',
|
|
3831
|
+
'spojuje',
|
|
3832
|
+
'dělí',
|
|
3833
|
+
'váže',
|
|
3834
|
+
'zraňuje',
|
|
3835
|
+
'chrání',
|
|
3836
|
+
'bojuje',
|
|
3837
|
+
'brání',
|
|
3838
|
+
'útočí',
|
|
3839
|
+
'uniká',
|
|
3840
|
+
'lapá',
|
|
3841
|
+
'osvobozuje',
|
|
3842
|
+
'poutá',
|
|
3843
|
+
'spřádá',
|
|
3844
|
+
'tká',
|
|
3845
|
+
'vrhá',
|
|
3846
|
+
'nese',
|
|
3847
|
+
'přenáší',
|
|
3848
|
+
'vrací',
|
|
3849
|
+
'zrychluje',
|
|
3850
|
+
'zpomaluje',
|
|
3851
|
+
'probouzí',
|
|
3852
|
+
'uspává',
|
|
3853
|
+
'šeptá',
|
|
3854
|
+
'volá',
|
|
3855
|
+
'hledí',
|
|
3856
|
+
'čeká',
|
|
3857
|
+
'bdí',
|
|
3858
|
+
'rozkvétá',
|
|
3859
|
+
'klíčí',
|
|
3860
|
+
'zraje',
|
|
3861
|
+
'chvěje',
|
|
3862
|
+
'třpytí',
|
|
3863
|
+
'shromažďuje',
|
|
3864
|
+
'rozhazuje',
|
|
3865
|
+
'tápe',
|
|
3866
|
+
'žhne',
|
|
3867
|
+
'vibruje',
|
|
3868
|
+
'šumí',
|
|
3869
|
+
'stéká',
|
|
3870
|
+
'vypráví',
|
|
3871
|
+
'plánuje',
|
|
3872
|
+
'počítá',
|
|
3873
|
+
'váhá',
|
|
3874
|
+
'riskuje',
|
|
3283
3875
|
];
|
|
3284
3876
|
/**
|
|
3285
|
-
*
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
const expandedHash = `${hash}${hash}`;
|
|
3289
|
-
const start = (segmentIndex * HASH_SEGMENT_LENGTH + segmentIndex) % hash.length;
|
|
3290
|
-
return parseInt(expandedHash.substring(start, start + HASH_SEGMENT_LENGTH), 16);
|
|
3291
|
-
}
|
|
3292
|
-
/**
|
|
3293
|
-
* Picks a deterministic item from a list based on the hash seed.
|
|
3294
|
-
*/
|
|
3295
|
-
function pickFromHash(hash, segmentIndex, list) {
|
|
3296
|
-
const seed = getHashSeed(hash, segmentIndex);
|
|
3297
|
-
return list[seed % list.length];
|
|
3298
|
-
}
|
|
3299
|
-
/**
|
|
3300
|
-
* Index constants for story part selection to avoid magic numbers.
|
|
3301
|
-
*/
|
|
3302
|
-
const ADJECTIVE3_INDEX = 9;
|
|
3303
|
-
const NOUN3_INDEX = 10;
|
|
3304
|
-
/**
|
|
3305
|
-
* Creates the deterministic story parts used by the sentence templates.
|
|
3877
|
+
* Czech word lists used by the linguistic hash.
|
|
3878
|
+
*
|
|
3879
|
+
* @private utility of `linguisticHash`
|
|
3306
3880
|
*/
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
adjective1: pickFromHash(hash, 3, ADJECTIVES),
|
|
3313
|
-
noun1: pickFromHash(hash, 4, NOUNS),
|
|
3314
|
-
verb1: pickFromHash(hash, 5, VERBS),
|
|
3315
|
-
adjective2: pickFromHash(hash, 6, ADJECTIVES),
|
|
3316
|
-
noun2: pickFromHash(hash, 7, NOUNS),
|
|
3317
|
-
verb2: pickFromHash(hash, 8, VERBS),
|
|
3318
|
-
adjective3: pickFromHash(hash, ADJECTIVE3_INDEX, ADJECTIVES),
|
|
3319
|
-
noun3: pickFromHash(hash, NOUN3_INDEX, NOUNS),
|
|
3320
|
-
};
|
|
3321
|
-
}
|
|
3881
|
+
const LINGUISTIC_HASH_WORD_LISTS_CS = {
|
|
3882
|
+
adjective: ADJECTIVES$1,
|
|
3883
|
+
noun: NOUNS$1,
|
|
3884
|
+
verb: VERBS$1,
|
|
3885
|
+
};
|
|
3322
3886
|
/**
|
|
3323
|
-
*
|
|
3887
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
3324
3888
|
*/
|
|
3325
|
-
|
|
3889
|
+
|
|
3326
3890
|
/**
|
|
3327
|
-
*
|
|
3891
|
+
* @@@
|
|
3892
|
+
*
|
|
3893
|
+
* @private utility of `linguisticHash`
|
|
3328
3894
|
*/
|
|
3329
|
-
function createStorySentence(hash) {
|
|
3330
|
-
const parts = createStoryParts(hash);
|
|
3331
|
-
const template = pickFromHash(hash, STORY_TEMPLATE_INDEX, STORY_TEMPLATES);
|
|
3332
|
-
return template(parts).trim();
|
|
3333
|
-
}
|
|
3334
3895
|
const ADJECTIVES = [
|
|
3335
3896
|
'red',
|
|
3336
3897
|
'blue',
|
|
@@ -4005,8 +4566,227 @@ const VERBS = [
|
|
|
4005
4566
|
'spinning',
|
|
4006
4567
|
];
|
|
4007
4568
|
/**
|
|
4008
|
-
*
|
|
4569
|
+
* English word lists used by the linguistic hash.
|
|
4570
|
+
*
|
|
4571
|
+
* @private utility of `linguisticHash`
|
|
4572
|
+
*/
|
|
4573
|
+
const LINGUISTIC_HASH_WORD_LISTS_EN = {
|
|
4574
|
+
adjective: ADJECTIVES,
|
|
4575
|
+
noun: NOUNS,
|
|
4576
|
+
verb: VERBS,
|
|
4577
|
+
};
|
|
4578
|
+
/**
|
|
4579
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
4580
|
+
*/
|
|
4581
|
+
|
|
4582
|
+
/**
|
|
4583
|
+
* Default language used for linguistic hashes.
|
|
4584
|
+
*
|
|
4585
|
+
* @private utility of `linguisticHash`
|
|
4586
|
+
*/
|
|
4587
|
+
const DEFAULT_LINGUISTIC_HASH_LANGUAGE = 'en';
|
|
4588
|
+
/**
|
|
4589
|
+
* @@@
|
|
4590
|
+
*
|
|
4591
|
+
* @private utility of `linguisticHash`
|
|
4592
|
+
*/
|
|
4593
|
+
const LANGUAGE_CONFIGS = {
|
|
4594
|
+
en: {
|
|
4595
|
+
language: 'en',
|
|
4596
|
+
label: 'English',
|
|
4597
|
+
wordLists: LINGUISTIC_HASH_WORD_LISTS_EN,
|
|
4598
|
+
},
|
|
4599
|
+
cs: {
|
|
4600
|
+
language: 'cs',
|
|
4601
|
+
label: 'Czech',
|
|
4602
|
+
wordLists: LINGUISTIC_HASH_WORD_LISTS_CS,
|
|
4603
|
+
},
|
|
4604
|
+
};
|
|
4605
|
+
/**
|
|
4606
|
+
* Normalizes a requested language to a supported linguistic hash language.
|
|
4607
|
+
*
|
|
4608
|
+
* @private utility of `linguisticHash`
|
|
4609
|
+
*/
|
|
4610
|
+
function normalizeLinguisticHashLanguage(language) {
|
|
4611
|
+
if (typeof language !== 'string') {
|
|
4612
|
+
return DEFAULT_LINGUISTIC_HASH_LANGUAGE;
|
|
4613
|
+
}
|
|
4614
|
+
const normalized = language.trim().toLowerCase();
|
|
4615
|
+
if (normalized === 'cs') {
|
|
4616
|
+
return 'cs';
|
|
4617
|
+
}
|
|
4618
|
+
if (normalized === 'en') {
|
|
4619
|
+
return 'en';
|
|
4620
|
+
}
|
|
4621
|
+
return DEFAULT_LINGUISTIC_HASH_LANGUAGE;
|
|
4622
|
+
}
|
|
4623
|
+
/**
|
|
4624
|
+
* Returns the language configuration for linguistic hash generation.
|
|
4625
|
+
*
|
|
4626
|
+
* @private utility of `linguisticHash`
|
|
4627
|
+
*/
|
|
4628
|
+
function getLinguisticHashLanguageConfig(language) {
|
|
4629
|
+
const normalized = normalizeLinguisticHashLanguage(language);
|
|
4630
|
+
return LANGUAGE_CONFIGS[normalized];
|
|
4631
|
+
}
|
|
4632
|
+
|
|
4633
|
+
// <- TODO: !!!! Remove re-exports
|
|
4634
|
+
/**
|
|
4635
|
+
* Creates a human-readable hash as a short, story-like phrase.
|
|
4636
|
+
*
|
|
4637
|
+
* @param wordCount how many words to include (defaults to {@link DEFAULT_LINGUISTIC_HASH_WORD_COUNT}, clamped to
|
|
4638
|
+
* {@link MIN_LINGUISTIC_HASH_WORD_COUNT}..{@link MAX_LINGUISTIC_HASH_WORD_COUNT})
|
|
4639
|
+
* @param language optional language code (defaults to {@link DEFAULT_LINGUISTIC_HASH_LANGUAGE})
|
|
4640
|
+
*
|
|
4641
|
+
* @public exported from `@promptbook/utils`
|
|
4642
|
+
*/
|
|
4643
|
+
async function linguisticHash(input, wordCount, language) {
|
|
4644
|
+
const hash = computeHash(input);
|
|
4645
|
+
const normalizedWordCount = normalizeLinguisticHashWordCount(wordCount);
|
|
4646
|
+
const languageConfig = getLinguisticHashLanguageConfig(language);
|
|
4647
|
+
const words = createLinguisticHashWords(hash, normalizedWordCount, languageConfig.wordLists);
|
|
4648
|
+
return capitalize(words.join(' '));
|
|
4649
|
+
}
|
|
4650
|
+
/**
|
|
4651
|
+
* @@@
|
|
4652
|
+
*
|
|
4653
|
+
* @private utility of `linguisticHash`
|
|
4654
|
+
*/
|
|
4655
|
+
const HASH_SEGMENT_LENGTH = 8;
|
|
4656
|
+
/**
|
|
4657
|
+
* The minimum number of words for a linguistic hash.
|
|
4658
|
+
*
|
|
4659
|
+
* @private utility of `linguisticHash`
|
|
4660
|
+
*/
|
|
4661
|
+
const MIN_LINGUISTIC_HASH_WORD_COUNT = 1;
|
|
4662
|
+
/**
|
|
4663
|
+
* The default number of words for a linguistic hash.
|
|
4664
|
+
*
|
|
4665
|
+
* @private utility of `linguisticHash`
|
|
4666
|
+
*/
|
|
4667
|
+
const DEFAULT_LINGUISTIC_HASH_WORD_COUNT = 7;
|
|
4668
|
+
/**
|
|
4669
|
+
* Extracts a deterministic numeric seed from a SHA-256 hash.
|
|
4670
|
+
*
|
|
4671
|
+
* @private utility of `linguisticHash`
|
|
4672
|
+
*/
|
|
4673
|
+
function getHashSeed(hash, segmentIndex) {
|
|
4674
|
+
const expandedHash = `${hash}${hash}`;
|
|
4675
|
+
const start = (segmentIndex * HASH_SEGMENT_LENGTH + segmentIndex) % hash.length;
|
|
4676
|
+
return parseInt(expandedHash.substring(start, start + HASH_SEGMENT_LENGTH), 16);
|
|
4677
|
+
}
|
|
4678
|
+
/**
|
|
4679
|
+
* Picks a deterministic item from a list based on the hash seed.
|
|
4680
|
+
*
|
|
4681
|
+
* @private utility of `linguisticHash`
|
|
4682
|
+
*/
|
|
4683
|
+
function pickFromHash(hash, segmentIndex, list) {
|
|
4684
|
+
const seed = getHashSeed(hash, segmentIndex);
|
|
4685
|
+
return list[seed % list.length];
|
|
4686
|
+
}
|
|
4687
|
+
/**
|
|
4688
|
+
* Ordered word kinds used to build the linguistic hash output.
|
|
4689
|
+
*
|
|
4690
|
+
* @private utility of `linguisticHash`
|
|
4691
|
+
*/
|
|
4692
|
+
const WORD_SEQUENCE = [
|
|
4693
|
+
'adjective',
|
|
4694
|
+
'noun',
|
|
4695
|
+
'verb',
|
|
4696
|
+
'adjective',
|
|
4697
|
+
'noun',
|
|
4698
|
+
'verb',
|
|
4699
|
+
'adjective',
|
|
4700
|
+
'noun',
|
|
4701
|
+
'verb',
|
|
4702
|
+
'adjective',
|
|
4703
|
+
'noun',
|
|
4704
|
+
'verb',
|
|
4705
|
+
'adjective',
|
|
4706
|
+
'noun',
|
|
4707
|
+
'verb',
|
|
4708
|
+
'adjective',
|
|
4709
|
+
'noun',
|
|
4710
|
+
'verb',
|
|
4711
|
+
'adjective',
|
|
4712
|
+
'noun',
|
|
4713
|
+
];
|
|
4714
|
+
/**
|
|
4715
|
+
* The maximum number of words for a linguistic hash.
|
|
4716
|
+
*
|
|
4717
|
+
* @private utility of `linguisticHash`
|
|
4718
|
+
*/
|
|
4719
|
+
const MAX_LINGUISTIC_HASH_WORD_COUNT = WORD_SEQUENCE.length;
|
|
4720
|
+
/**
|
|
4721
|
+
* Index of the noun used for single-word hashes.
|
|
4722
|
+
*
|
|
4723
|
+
* @private utility of `linguisticHash`
|
|
4724
|
+
*/
|
|
4725
|
+
const SINGLE_WORD_INDEX = 1;
|
|
4726
|
+
/**
|
|
4727
|
+
* Normalizes the word count to a supported integer range.
|
|
4728
|
+
*
|
|
4729
|
+
* @private utility of `linguisticHash`
|
|
4730
|
+
*/
|
|
4731
|
+
function normalizeLinguisticHashWordCount(wordCount) {
|
|
4732
|
+
if (typeof wordCount !== 'number' || !Number.isFinite(wordCount)) {
|
|
4733
|
+
return DEFAULT_LINGUISTIC_HASH_WORD_COUNT;
|
|
4734
|
+
}
|
|
4735
|
+
const rounded = Math.round(wordCount);
|
|
4736
|
+
return Math.min(MAX_LINGUISTIC_HASH_WORD_COUNT, Math.max(MIN_LINGUISTIC_HASH_WORD_COUNT, rounded));
|
|
4737
|
+
}
|
|
4738
|
+
/**
|
|
4739
|
+
* Picks a deterministic word from the hash by kind.
|
|
4740
|
+
*
|
|
4741
|
+
* @private utility of `linguisticHash`
|
|
4742
|
+
*/
|
|
4743
|
+
function pickWordFromHash(hash, segmentIndex, wordKind, wordLists) {
|
|
4744
|
+
return pickFromHash(hash, segmentIndex, wordLists[wordKind]);
|
|
4745
|
+
}
|
|
4746
|
+
/**
|
|
4747
|
+
* Creates the deterministic word sequence used for the linguistic hash output.
|
|
4748
|
+
*
|
|
4749
|
+
* @private utility of `linguisticHash`
|
|
4750
|
+
*/
|
|
4751
|
+
function createLinguisticHashWordSequence(hash, wordLists) {
|
|
4752
|
+
return WORD_SEQUENCE.map((wordKind, index) => pickWordFromHash(hash, index, wordKind, wordLists));
|
|
4753
|
+
}
|
|
4754
|
+
/**
|
|
4755
|
+
* Selects the requested number of words from the hash output.
|
|
4756
|
+
*
|
|
4757
|
+
* @private utility of `linguisticHash`
|
|
4758
|
+
*/
|
|
4759
|
+
function createLinguisticHashWords(hash, wordCount, wordLists) {
|
|
4760
|
+
const words = createLinguisticHashWordSequence(hash, wordLists);
|
|
4761
|
+
if (wordCount === 1) {
|
|
4762
|
+
return [words[SINGLE_WORD_INDEX]];
|
|
4763
|
+
}
|
|
4764
|
+
return words.slice(0, wordCount);
|
|
4765
|
+
}
|
|
4766
|
+
|
|
4767
|
+
/**
|
|
4768
|
+
* Simple wrapper `new Date().toISOString()`
|
|
4769
|
+
*
|
|
4770
|
+
* Note: `$` is used to indicate that this function is not a pure function - it is not deterministic because it depends on the current time
|
|
4771
|
+
*
|
|
4772
|
+
* @returns string_date branded type
|
|
4773
|
+
* @public exported from `@promptbook/utils`
|
|
4774
|
+
*/
|
|
4775
|
+
function $getCurrentDate() {
|
|
4776
|
+
return new Date().toISOString();
|
|
4777
|
+
}
|
|
4778
|
+
|
|
4779
|
+
/**
|
|
4780
|
+
* @public exported from `@promptbook/utils`
|
|
4009
4781
|
*/
|
|
4782
|
+
function debounce(fn, delay) {
|
|
4783
|
+
let timeout = null;
|
|
4784
|
+
return (...args) => {
|
|
4785
|
+
if (timeout)
|
|
4786
|
+
clearTimeout(timeout);
|
|
4787
|
+
timeout = setTimeout(() => fn(...args), delay);
|
|
4788
|
+
};
|
|
4789
|
+
}
|
|
4010
4790
|
|
|
4011
4791
|
/**
|
|
4012
4792
|
* Function parseNumber will parse number from string
|