@promptbook/remote-server 0.106.0-0 → 0.107.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 CHANGED
@@ -39,7 +39,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
39
39
  * @generated
40
40
  * @see https://github.com/webgptorg/promptbook
41
41
  */
42
- const PROMPTBOOK_ENGINE_VERSION = '0.106.0-0';
42
+ const PROMPTBOOK_ENGINE_VERSION = '0.107.0-0';
43
43
  /**
44
44
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
45
45
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -8322,18 +8322,6 @@ function prompt(strings, ...values) {
8322
8322
  * Note: [💞] Ignore a discrepancy between file name and entity name
8323
8323
  */
8324
8324
 
8325
- /**
8326
- * Simple wrapper `new Date().toISOString()`
8327
- *
8328
- * Note: `$` is used to indicate that this function is not a pure function - it is not deterministic because it depends on the current time
8329
- *
8330
- * @returns string_date branded type
8331
- * @public exported from `@promptbook/utils`
8332
- */
8333
- function $getCurrentDate() {
8334
- return new Date().toISOString();
8335
- }
8336
-
8337
8325
  /**
8338
8326
  * Computes SHA-256 hash of the given object
8339
8327
  *
@@ -8346,103 +8334,564 @@ function computeHash(value) {
8346
8334
  * TODO: [🥬][🥬] Use this ACRY
8347
8335
  */
8348
8336
 
8337
+ // spell-checker: disable
8349
8338
  /**
8350
- * Creates a human-readable hash as a short story sentence.
8339
+ * @@@
8351
8340
  *
8352
- * @public exported from `@promptbook/utils`
8353
- */
8354
- async function linguisticHash(input) {
8355
- const hash = computeHash(input);
8356
- return capitalize(createStorySentence(hash));
8357
- }
8358
- const HASH_SEGMENT_LENGTH = 8;
8359
- const STORY_OPENERS = [
8360
- 'once',
8361
- 'long ago',
8362
- 'at dawn',
8363
- 'at dusk',
8364
- 'suddenly',
8365
- 'quietly',
8366
- 'meanwhile',
8367
- 'today',
8368
- 'tonight',
8369
- 'in the end',
8370
- 'before long',
8371
- 'for a moment',
8341
+ * @private utility of `linguisticHash`
8342
+ */
8343
+ const ADJECTIVES$1 = [
8344
+ 'červený',
8345
+ 'modrý',
8346
+ 'zelený',
8347
+ 'žlutý',
8348
+ 'rychlý',
8349
+ 'pomalý',
8350
+ 'jasný',
8351
+ 'temný',
8352
+ 'veselý',
8353
+ 'smutný',
8354
+ 'statečný',
8355
+ 'klidný',
8356
+ 'chytrý',
8357
+ 'bystrý',
8358
+ 'dychtivý',
8359
+ 'honosný',
8360
+ 'velkolepý',
8361
+ 'hravý',
8362
+ 'laskavý',
8363
+ 'šťastný',
8364
+ 'hrdý',
8365
+ 'pošetilý',
8366
+ 'moudrý',
8367
+ 'mladý',
8368
+ 'starý',
8369
+ 'veliký',
8370
+ 'malý',
8371
+ 'drobný',
8372
+ 'obrovský',
8373
+ 'krátký',
8374
+ 'dlouhý',
8375
+ 'blízký',
8376
+ 'vzdálený',
8377
+ 'vnitřní',
8378
+ 'vnější',
8379
+ 'trpělivý',
8380
+ 'stálý',
8381
+ 'ušlechtilý',
8382
+ 'čistý',
8383
+ 'špinavý',
8384
+ 'čerstvý',
8385
+ 'zvětralý',
8386
+ 'ostrý',
8387
+ 'tupý',
8388
+ 'tlustý',
8389
+ 'tenký',
8390
+ 'široký',
8391
+ 'úzký',
8392
+ 'hluboký',
8393
+ 'mělký',
8394
+ 'mocný',
8395
+ 'jemný',
8396
+ 'divoký',
8397
+ 'tichý',
8398
+ 'hlučný',
8399
+ 'pokojný',
8400
+ 'rušný',
8401
+ 'prázdný',
8402
+ 'plný',
8403
+ 'kulatý',
8404
+ 'hranatý',
8405
+ 'plochý',
8406
+ 'křivý',
8407
+ 'tvrdý',
8408
+ 'měkký',
8409
+ 'teplý',
8410
+ 'chladný',
8411
+ 'sladký',
8412
+ 'kyselý',
8413
+ 'hořký',
8414
+ 'slaný',
8415
+ 'silný',
8416
+ 'slabý',
8417
+ 'pevný',
8418
+ 'pružný',
8419
+ 'křehký',
8420
+ 'houževnatý',
8421
+ 'lesklý',
8422
+ 'matný',
8423
+ 'kluzký',
8424
+ 'lepkavý',
8425
+ 'svěží',
8426
+ 'vybledlý',
8427
+ 'mlhavý',
8428
+ 'bouřlivý',
8429
+ 'slunný',
8430
+ 'větrný',
8431
+ 'deštivý',
8432
+ 'mrazivý',
8433
+ 'zlatý',
8434
+ 'stříbrný',
8435
+ 'ledový',
8436
+ 'žhavý',
8437
+ 'prastarý',
8438
+ 'moderní',
8439
+ 'skrytý',
8440
+ 'ztracený',
8441
+ 'nalezený',
8442
+ 'magický',
8443
+ 'tajemný',
8444
+ 'kosmický',
8445
+ 'hvězdný',
8446
+ 'měsíční',
8447
+ 'sluneční',
8448
+ 'mlžný',
8449
+ 'ranní',
8450
+ 'večerní',
8451
+ 'noční',
8452
+ 'denní',
8453
+ 'osamělý',
8454
+ 'společenský',
8455
+ 'soukromý',
8456
+ 'veřejný',
8457
+ 'tajný',
8458
+ 'slavný',
8459
+ 'jistý',
8460
+ 'neurčitý',
8461
+ 'prostý',
8462
+ 'snadný',
8463
+ 'krotký',
8464
+ 'mírný',
8465
+ 'horký',
8466
+ 'suchý',
8467
+ 'mokrý',
8468
+ 'vlhký',
8469
+ 'promočený',
8470
+ 'vyprahlý',
8471
+ 'hladový',
8472
+ 'žíznivý',
8473
+ 'ospalý',
8474
+ 'bdělý',
8475
+ 'unavený',
8476
+ 'líný',
8477
+ 'neklidný',
8478
+ 'nestálý',
8479
+ 'odvážný',
8480
+ 'bázlivý',
8481
+ 'upřímný',
8482
+ 'věrný',
8483
+ 'pravý',
8484
+ 'falešný',
8485
+ 'spravedlivý',
8486
+ 'jednoduchý',
8487
+ 'složitý',
8488
+ 'přirozený',
8489
+ 'umělý',
8490
+ 'živý',
8491
+ 'mrtvý',
8492
+ 'zvídavý',
8493
+ 'zvláštní',
8494
+ 'běžný',
8495
+ 'vzácný',
8496
+ 'jedinečný',
8497
+ 'základní',
8498
+ 'prvotní',
8499
+ 'hbitý',
8372
8500
  ];
8373
- const STORY_CONNECTORS = ['while', 'as', 'when', 'because', 'and', 'just as', 'after', 'before'];
8374
- const STORY_PREPOSITIONS = [
8375
- 'near',
8376
- 'beside',
8377
- 'under',
8378
- 'within',
8379
- 'beyond',
8380
- 'around',
8381
- 'behind',
8382
- 'across',
8383
- 'above',
8384
- 'beneath',
8385
- 'over',
8386
- 'inside',
8387
- 'outside',
8388
- 'along',
8501
+ const NOUNS$1 = [
8502
+ 'jablko',
8503
+ 'nebe',
8504
+ 'strom',
8505
+ 'liška',
8506
+ 'kočka',
8507
+ 'pták',
8508
+ 'pes',
8509
+ 'řeka',
8510
+ 'hora',
8511
+ 'les',
8512
+ 'oceán',
8513
+ 'hvězda',
8514
+ 'měsíc',
8515
+ 'slunce',
8516
+ 'mrak',
8517
+ 'květ',
8518
+ 'list',
8519
+ 'kámen',
8520
+ 'vítr',
8521
+ 'déšť',
8522
+ 'oheň',
8523
+ 'led',
8524
+ 'kniha',
8525
+ 'sen',
8526
+ 'píseň',
8527
+ 'cesta',
8528
+ 'brána',
8529
+ 'klíč',
8530
+ 'lampa',
8531
+ 'mapa',
8532
+ 'dům',
8533
+ 'město',
8534
+ 'most',
8535
+ 'pole',
8536
+ 'zahrada',
8537
+ 'jezero',
8538
+ 'pláž',
8539
+ 'ostrov',
8540
+ 'údolí',
8541
+ 'poušť',
8542
+ 'svět',
8543
+ 'duch',
8544
+ 'srdce',
8545
+ 'mysl',
8546
+ 'duše',
8547
+ 'život',
8548
+ 'čas',
8549
+ 'prostor',
8550
+ 'světlo',
8551
+ 'stín',
8552
+ 'zvuk',
8553
+ 'hudba',
8554
+ 'hlas',
8555
+ 'slovo',
8556
+ 'stránka',
8557
+ 'příběh',
8558
+ 'perla',
8559
+ 'zlato',
8560
+ 'stříbro',
8561
+ 'krystal',
8562
+ 'diamant',
8563
+ 'smaragd',
8564
+ 'rubín',
8565
+ 'stezka',
8566
+ 'vrchol',
8567
+ 'břeh',
8568
+ 'vlna',
8569
+ 'příliv',
8570
+ 'plamen',
8571
+ 'jiskra',
8572
+ 'paprsek',
8573
+ 'semínko',
8574
+ 'kořen',
8575
+ 'větev',
8576
+ 'pupen',
8577
+ 'trn',
8578
+ 'kůra',
8579
+ 'skořápka',
8580
+ 'pírko',
8581
+ 'křídlo',
8582
+ 'dráp',
8583
+ 'tlapa',
8584
+ 'hnízdo',
8585
+ 'jeskyně',
8586
+ 'hájek',
8587
+ 'věž',
8588
+ 'hrad',
8589
+ 'koruna',
8590
+ 'meč',
8591
+ 'štít',
8592
+ 'mince',
8593
+ 'drahokam',
8594
+ 'prsten',
8595
+ 'zvonek',
8596
+ 'hodiny',
8597
+ 'kompas',
8598
+ 'kotva',
8599
+ 'pochodeň',
8600
+ 'flétna',
8601
+ 'harfa',
8602
+ 'buben',
8603
+ 'čočka',
8604
+ 'sklo',
8605
+ 'písek',
8606
+ 'prach',
8607
+ 'mlha',
8608
+ 'rosa',
8609
+ 'svítání',
8610
+ 'soumrak',
8611
+ 'noc',
8612
+ 'den',
8613
+ 'rok',
8614
+ 'věk',
8615
+ 'blesk',
8616
+ 'kapka',
8617
+ 'bouře',
8618
+ 'sníh',
8619
+ 'kroupa',
8620
+ 'kouř',
8621
+ 'pára',
8622
+ 'plyn',
8623
+ 'kov',
8624
+ 'skála',
8625
+ 'hlína',
8626
+ 'sůl',
8627
+ 'cukr',
8628
+ 'dřevo',
8629
+ 'kost',
8630
+ 'kůže',
8631
+ 'tělo',
8632
+ 'krev',
8633
+ 'buňka',
8634
+ 'atom',
8635
+ 'tep',
8636
+ 'dech',
8637
+ 'vzdech',
8638
+ 'jméno',
8639
+ 'ozvěna',
8640
+ 'obraz',
8641
+ 'vize',
8642
+ 'myšlenka',
8643
+ 'nápad',
8644
+ 'plán',
8645
+ 'cíl',
8646
+ 'přání',
8647
+ 'naděje',
8648
+ 'strach',
8649
+ 'radost',
8650
+ 'láska',
8651
+ 'nenávist',
8652
+ 'vůle',
8653
+ 'síla',
8654
+ 'energie',
8655
+ 'pohyb',
8656
+ 'rychlost',
8657
+ 'místo',
8658
+ 'bod',
8659
+ 'linie',
8660
+ 'tvar',
8661
+ 'forma',
8662
+ 'velikost',
8663
+ 'hmota',
8664
+ 'váha',
8665
+ 'teplo',
8666
+ 'chlad',
8667
+ 'barva',
8668
+ 'tón',
8669
+ 'rytmus',
8670
+ 'nálada',
8671
+ 'stav',
8672
+ 'krok',
8673
+ 'pád',
8674
+ 'skok',
8675
+ 'běh',
8676
+ 'let',
8677
+ 'klid',
8678
+ 'úkol',
8679
+ 'práce',
8680
+ 'hra',
8681
+ 'sport',
8682
+ 'umění',
8683
+ 'řemeslo',
8684
+ 'nástroj',
8685
+ 'loď',
8686
+ 'člun',
8687
+ 'auto',
8688
+ 'kolo',
8689
+ 'vlak',
8690
+ 'letadlo',
8691
+ 'uzel',
8692
+ 'síť',
8693
+ 'krabice',
8694
+ 'taška',
8695
+ 'dóza',
8696
+ 'hrnek',
8697
+ 'miska',
8698
+ 'talíř',
8699
+ 'lžíce',
8700
+ 'vidlička',
8701
+ 'nůž',
8702
+ 'pánev',
8703
+ 'hrnec',
8704
+ 'postel',
8705
+ 'stůl',
8706
+ 'židle',
8707
+ 'dveře',
8708
+ 'stěna',
8709
+ 'střecha',
8710
+ 'podlaha',
8711
+ 'okno',
8712
+ 'chodba',
8389
8713
  ];
8390
- const STORY_TEMPLATES = [
8391
- (parts) => `${parts.opener}, the ${parts.adjective1} ${parts.noun1} was ${parts.verb1} ${parts.connector} the ${parts.adjective2} ${parts.noun2} was ${parts.verb2} ${parts.preposition} the ${parts.adjective3} ${parts.noun3}.`,
8392
- (parts) => `${parts.opener}, the ${parts.adjective1} ${parts.noun1} was ${parts.verb1} ${parts.preposition} the ${parts.adjective2} ${parts.noun2}, and the ${parts.adjective3} ${parts.noun3} was ${parts.verb2}.`,
8393
- (parts) => `${parts.opener}, the ${parts.adjective1} ${parts.noun1} was ${parts.verb1}, and the ${parts.adjective2} ${parts.noun2} was ${parts.verb2} ${parts.preposition} the ${parts.adjective3} ${parts.noun3}.`,
8394
- (parts) => `${parts.opener}, the ${parts.adjective1} ${parts.noun1} was ${parts.verb1} ${parts.connector} the ${parts.adjective2} ${parts.noun2} was ${parts.verb2}, ${parts.preposition} the ${parts.adjective3} ${parts.noun3}.`,
8714
+ const VERBS$1 = [
8715
+ 'skáče',
8716
+ 'tančí',
8717
+ 'letí',
8718
+ 'běží',
8719
+ 'zpívá',
8720
+ 'svítí',
8721
+ 'roste',
8722
+ 'plyne',
8723
+ 'padá',
8724
+ 'stoupá',
8725
+ 'spí',
8726
+ 'kráčí',
8727
+ 'mluví',
8728
+ 'myslí',
8729
+ 'sní',
8730
+ 'hledá',
8731
+ 'nachází',
8732
+ 'dává',
8733
+ 'bere',
8734
+ 'tvoří',
8735
+ 'hoří',
8736
+ 'mrzne',
8737
+ 'taje',
8738
+ 'dýchá',
8739
+ 'pulzuje',
8740
+ 'bije',
8741
+ 'žije',
8742
+ 'učí',
8743
+ 'ví',
8744
+ 'skrývá',
8745
+ 'ukazuje',
8746
+ 'láme',
8747
+ 'opravuje',
8748
+ 'ztrácí',
8749
+ 'nalézá',
8750
+ 'začíná',
8751
+ 'končí',
8752
+ 'plave',
8753
+ 'pluje',
8754
+ 'klouže',
8755
+ 'točí',
8756
+ 'mění',
8757
+ 'bledne',
8758
+ 'mizí',
8759
+ 'rodí',
8760
+ 'hučí',
8761
+ 'pláče',
8762
+ 'závodí',
8763
+ 'plíží',
8764
+ 'sleduje',
8765
+ 'slyší',
8766
+ 'cítí',
8767
+ 'touží',
8768
+ 'doufá',
8769
+ 'miluje',
8770
+ 'bloudí',
8771
+ 'putuje',
8772
+ 'cestuje',
8773
+ 'překračuje',
8774
+ 'potkává',
8775
+ 'drží',
8776
+ 'sdílí',
8777
+ 'jiskří',
8778
+ 'plápolá',
8779
+ 'léčí',
8780
+ 'řeší',
8781
+ 'otevírá',
8782
+ 'zavírá',
8783
+ 'zvedá',
8784
+ 'táhne',
8785
+ 'tlačí',
8786
+ 'hází',
8787
+ 'chytá',
8788
+ 'dělá',
8789
+ 'vidí',
8790
+ 'chutná',
8791
+ 'voní',
8792
+ 'spěchá',
8793
+ 'zastaví',
8794
+ 'jde',
8795
+ 'přichází',
8796
+ 'odchází',
8797
+ 'jedná',
8798
+ 'existuje',
8799
+ 'zmenšuje',
8800
+ 'rozšiřuje',
8801
+ 'zužuje',
8802
+ 'hřeje',
8803
+ 'chladí',
8804
+ 'suší',
8805
+ 'máčí',
8806
+ 'plní',
8807
+ 'vyprazdňuje',
8808
+ 'pouští',
8809
+ 'získává',
8810
+ 'vítězí',
8811
+ 'selhává',
8812
+ 'zkouší',
8813
+ 'používá',
8814
+ 'dostává',
8815
+ 'měří',
8816
+ 'stojí',
8817
+ 'dosahuje',
8818
+ 'míjí',
8819
+ 'udeří',
8820
+ 'vede',
8821
+ 'následuje',
8822
+ 'pomáhá',
8823
+ 'slouží',
8824
+ 'trénuje',
8825
+ 'kóduje',
8826
+ 'píše',
8827
+ 'čte',
8828
+ 'kreslí',
8829
+ 'maluje',
8830
+ 'tvaruje',
8831
+ 'spojuje',
8832
+ 'dělí',
8833
+ 'váže',
8834
+ 'zraňuje',
8835
+ 'chrání',
8836
+ 'bojuje',
8837
+ 'brání',
8838
+ 'útočí',
8839
+ 'uniká',
8840
+ 'lapá',
8841
+ 'osvobozuje',
8842
+ 'poutá',
8843
+ 'spřádá',
8844
+ 'tká',
8845
+ 'vrhá',
8846
+ 'nese',
8847
+ 'přenáší',
8848
+ 'vrací',
8849
+ 'zrychluje',
8850
+ 'zpomaluje',
8851
+ 'probouzí',
8852
+ 'uspává',
8853
+ 'šeptá',
8854
+ 'volá',
8855
+ 'hledí',
8856
+ 'čeká',
8857
+ 'bdí',
8858
+ 'rozkvétá',
8859
+ 'klíčí',
8860
+ 'zraje',
8861
+ 'chvěje',
8862
+ 'třpytí',
8863
+ 'shromažďuje',
8864
+ 'rozhazuje',
8865
+ 'tápe',
8866
+ 'žhne',
8867
+ 'vibruje',
8868
+ 'šumí',
8869
+ 'stéká',
8870
+ 'vypráví',
8871
+ 'plánuje',
8872
+ 'počítá',
8873
+ 'váhá',
8874
+ 'riskuje',
8395
8875
  ];
8396
8876
  /**
8397
- * Extracts a deterministic numeric seed from a SHA-256 hash.
8398
- */
8399
- function getHashSeed(hash, segmentIndex) {
8400
- const expandedHash = `${hash}${hash}`;
8401
- const start = (segmentIndex * HASH_SEGMENT_LENGTH + segmentIndex) % hash.length;
8402
- return parseInt(expandedHash.substring(start, start + HASH_SEGMENT_LENGTH), 16);
8403
- }
8404
- /**
8405
- * Picks a deterministic item from a list based on the hash seed.
8406
- */
8407
- function pickFromHash(hash, segmentIndex, list) {
8408
- const seed = getHashSeed(hash, segmentIndex);
8409
- return list[seed % list.length];
8410
- }
8411
- /**
8412
- * Index constants for story part selection to avoid magic numbers.
8413
- */
8414
- const ADJECTIVE3_INDEX = 9;
8415
- const NOUN3_INDEX = 10;
8416
- /**
8417
- * Creates the deterministic story parts used by the sentence templates.
8877
+ * Czech word lists used by the linguistic hash.
8878
+ *
8879
+ * @private utility of `linguisticHash`
8418
8880
  */
8419
- function createStoryParts(hash) {
8420
- return {
8421
- opener: pickFromHash(hash, 0, STORY_OPENERS),
8422
- connector: pickFromHash(hash, 1, STORY_CONNECTORS),
8423
- preposition: pickFromHash(hash, 2, STORY_PREPOSITIONS),
8424
- adjective1: pickFromHash(hash, 3, ADJECTIVES),
8425
- noun1: pickFromHash(hash, 4, NOUNS),
8426
- verb1: pickFromHash(hash, 5, VERBS),
8427
- adjective2: pickFromHash(hash, 6, ADJECTIVES),
8428
- noun2: pickFromHash(hash, 7, NOUNS),
8429
- verb2: pickFromHash(hash, 8, VERBS),
8430
- adjective3: pickFromHash(hash, ADJECTIVE3_INDEX, ADJECTIVES),
8431
- noun3: pickFromHash(hash, NOUN3_INDEX, NOUNS),
8432
- };
8433
- }
8881
+ const LINGUISTIC_HASH_WORD_LISTS_CS = {
8882
+ adjective: ADJECTIVES$1,
8883
+ noun: NOUNS$1,
8884
+ verb: VERBS$1,
8885
+ };
8434
8886
  /**
8435
- * Index constant for story template selection to avoid magic numbers.
8887
+ * Note: [💞] Ignore a discrepancy between file name and entity name
8436
8888
  */
8437
- const STORY_TEMPLATE_INDEX = 11;
8889
+
8438
8890
  /**
8439
- * Builds a short, memorable story sentence from the hash.
8891
+ * @@@
8892
+ *
8893
+ * @private utility of `linguisticHash`
8440
8894
  */
8441
- function createStorySentence(hash) {
8442
- const parts = createStoryParts(hash);
8443
- const template = pickFromHash(hash, STORY_TEMPLATE_INDEX, STORY_TEMPLATES);
8444
- return template(parts).trim();
8445
- }
8446
8895
  const ADJECTIVES = [
8447
8896
  'red',
8448
8897
  'blue',
@@ -9117,9 +9566,216 @@ const VERBS = [
9117
9566
  'spinning',
9118
9567
  ];
9119
9568
  /**
9120
- * TODO: Prompt: Extract number constants and word list to a separate file for reuse.
9569
+ * English word lists used by the linguistic hash.
9570
+ *
9571
+ * @private utility of `linguisticHash`
9572
+ */
9573
+ const LINGUISTIC_HASH_WORD_LISTS_EN = {
9574
+ adjective: ADJECTIVES,
9575
+ noun: NOUNS,
9576
+ verb: VERBS,
9577
+ };
9578
+ /**
9579
+ * Note: [💞] Ignore a discrepancy between file name and entity name
9121
9580
  */
9122
9581
 
9582
+ /**
9583
+ * Default language used for linguistic hashes.
9584
+ *
9585
+ * @private utility of `linguisticHash`
9586
+ */
9587
+ const DEFAULT_LINGUISTIC_HASH_LANGUAGE = 'en';
9588
+ /**
9589
+ * @@@
9590
+ *
9591
+ * @private utility of `linguisticHash`
9592
+ */
9593
+ const LANGUAGE_CONFIGS = {
9594
+ en: {
9595
+ language: 'en',
9596
+ label: 'English',
9597
+ wordLists: LINGUISTIC_HASH_WORD_LISTS_EN,
9598
+ },
9599
+ cs: {
9600
+ language: 'cs',
9601
+ label: 'Czech',
9602
+ wordLists: LINGUISTIC_HASH_WORD_LISTS_CS,
9603
+ },
9604
+ };
9605
+ /**
9606
+ * Normalizes a requested language to a supported linguistic hash language.
9607
+ *
9608
+ * @private utility of `linguisticHash`
9609
+ */
9610
+ function normalizeLinguisticHashLanguage(language) {
9611
+ if (typeof language !== 'string') {
9612
+ return DEFAULT_LINGUISTIC_HASH_LANGUAGE;
9613
+ }
9614
+ const normalized = language.trim().toLowerCase();
9615
+ if (normalized === 'cs') {
9616
+ return 'cs';
9617
+ }
9618
+ if (normalized === 'en') {
9619
+ return 'en';
9620
+ }
9621
+ return DEFAULT_LINGUISTIC_HASH_LANGUAGE;
9622
+ }
9623
+ /**
9624
+ * Returns the language configuration for linguistic hash generation.
9625
+ *
9626
+ * @private utility of `linguisticHash`
9627
+ */
9628
+ function getLinguisticHashLanguageConfig(language) {
9629
+ const normalized = normalizeLinguisticHashLanguage(language);
9630
+ return LANGUAGE_CONFIGS[normalized];
9631
+ }
9632
+
9633
+ // <- TODO: !!!! Remove re-exports
9634
+ /**
9635
+ * Creates a human-readable hash as a short, story-like phrase.
9636
+ *
9637
+ * @param wordCount how many words to include (defaults to {@link DEFAULT_LINGUISTIC_HASH_WORD_COUNT}, clamped to
9638
+ * {@link MIN_LINGUISTIC_HASH_WORD_COUNT}..{@link MAX_LINGUISTIC_HASH_WORD_COUNT})
9639
+ * @param language optional language code (defaults to {@link DEFAULT_LINGUISTIC_HASH_LANGUAGE})
9640
+ *
9641
+ * @public exported from `@promptbook/utils`
9642
+ */
9643
+ async function linguisticHash(input, wordCount, language) {
9644
+ const hash = computeHash(input);
9645
+ const normalizedWordCount = normalizeLinguisticHashWordCount(wordCount);
9646
+ const languageConfig = getLinguisticHashLanguageConfig(language);
9647
+ const words = createLinguisticHashWords(hash, normalizedWordCount, languageConfig.wordLists);
9648
+ return capitalize(words.join(' '));
9649
+ }
9650
+ /**
9651
+ * @@@
9652
+ *
9653
+ * @private utility of `linguisticHash`
9654
+ */
9655
+ const HASH_SEGMENT_LENGTH = 8;
9656
+ /**
9657
+ * The minimum number of words for a linguistic hash.
9658
+ *
9659
+ * @private utility of `linguisticHash`
9660
+ */
9661
+ const MIN_LINGUISTIC_HASH_WORD_COUNT = 1;
9662
+ /**
9663
+ * The default number of words for a linguistic hash.
9664
+ *
9665
+ * @private utility of `linguisticHash`
9666
+ */
9667
+ const DEFAULT_LINGUISTIC_HASH_WORD_COUNT = 7;
9668
+ /**
9669
+ * Extracts a deterministic numeric seed from a SHA-256 hash.
9670
+ *
9671
+ * @private utility of `linguisticHash`
9672
+ */
9673
+ function getHashSeed(hash, segmentIndex) {
9674
+ const expandedHash = `${hash}${hash}`;
9675
+ const start = (segmentIndex * HASH_SEGMENT_LENGTH + segmentIndex) % hash.length;
9676
+ return parseInt(expandedHash.substring(start, start + HASH_SEGMENT_LENGTH), 16);
9677
+ }
9678
+ /**
9679
+ * Picks a deterministic item from a list based on the hash seed.
9680
+ *
9681
+ * @private utility of `linguisticHash`
9682
+ */
9683
+ function pickFromHash(hash, segmentIndex, list) {
9684
+ const seed = getHashSeed(hash, segmentIndex);
9685
+ return list[seed % list.length];
9686
+ }
9687
+ /**
9688
+ * Ordered word kinds used to build the linguistic hash output.
9689
+ *
9690
+ * @private utility of `linguisticHash`
9691
+ */
9692
+ const WORD_SEQUENCE = [
9693
+ 'adjective',
9694
+ 'noun',
9695
+ 'verb',
9696
+ 'adjective',
9697
+ 'noun',
9698
+ 'verb',
9699
+ 'adjective',
9700
+ 'noun',
9701
+ 'verb',
9702
+ 'adjective',
9703
+ 'noun',
9704
+ 'verb',
9705
+ 'adjective',
9706
+ 'noun',
9707
+ 'verb',
9708
+ 'adjective',
9709
+ 'noun',
9710
+ 'verb',
9711
+ 'adjective',
9712
+ 'noun',
9713
+ ];
9714
+ /**
9715
+ * The maximum number of words for a linguistic hash.
9716
+ *
9717
+ * @private utility of `linguisticHash`
9718
+ */
9719
+ const MAX_LINGUISTIC_HASH_WORD_COUNT = WORD_SEQUENCE.length;
9720
+ /**
9721
+ * Index of the noun used for single-word hashes.
9722
+ *
9723
+ * @private utility of `linguisticHash`
9724
+ */
9725
+ const SINGLE_WORD_INDEX = 1;
9726
+ /**
9727
+ * Normalizes the word count to a supported integer range.
9728
+ *
9729
+ * @private utility of `linguisticHash`
9730
+ */
9731
+ function normalizeLinguisticHashWordCount(wordCount) {
9732
+ if (typeof wordCount !== 'number' || !Number.isFinite(wordCount)) {
9733
+ return DEFAULT_LINGUISTIC_HASH_WORD_COUNT;
9734
+ }
9735
+ const rounded = Math.round(wordCount);
9736
+ return Math.min(MAX_LINGUISTIC_HASH_WORD_COUNT, Math.max(MIN_LINGUISTIC_HASH_WORD_COUNT, rounded));
9737
+ }
9738
+ /**
9739
+ * Picks a deterministic word from the hash by kind.
9740
+ *
9741
+ * @private utility of `linguisticHash`
9742
+ */
9743
+ function pickWordFromHash(hash, segmentIndex, wordKind, wordLists) {
9744
+ return pickFromHash(hash, segmentIndex, wordLists[wordKind]);
9745
+ }
9746
+ /**
9747
+ * Creates the deterministic word sequence used for the linguistic hash output.
9748
+ *
9749
+ * @private utility of `linguisticHash`
9750
+ */
9751
+ function createLinguisticHashWordSequence(hash, wordLists) {
9752
+ return WORD_SEQUENCE.map((wordKind, index) => pickWordFromHash(hash, index, wordKind, wordLists));
9753
+ }
9754
+ /**
9755
+ * Selects the requested number of words from the hash output.
9756
+ *
9757
+ * @private utility of `linguisticHash`
9758
+ */
9759
+ function createLinguisticHashWords(hash, wordCount, wordLists) {
9760
+ const words = createLinguisticHashWordSequence(hash, wordLists);
9761
+ if (wordCount === 1) {
9762
+ return [words[SINGLE_WORD_INDEX]];
9763
+ }
9764
+ return words.slice(0, wordCount);
9765
+ }
9766
+
9767
+ /**
9768
+ * Simple wrapper `new Date().toISOString()`
9769
+ *
9770
+ * Note: `$` is used to indicate that this function is not a pure function - it is not deterministic because it depends on the current time
9771
+ *
9772
+ * @returns string_date branded type
9773
+ * @public exported from `@promptbook/utils`
9774
+ */
9775
+ function $getCurrentDate() {
9776
+ return new Date().toISOString();
9777
+ }
9778
+
9123
9779
  /**
9124
9780
  * Makes first letter of a string lowercase
9125
9781
  *
@@ -16610,6 +17266,21 @@ function book(strings, ...values) {
16610
17266
  * Note: [💞] Ignore a discrepancy between file name and entity name
16611
17267
  */
16612
17268
 
17269
+ /**
17270
+ * Tool call name emitted while preparing a GPT assistant for an agent.
17271
+ *
17272
+ * @public exported from `@promptbook/types`
17273
+ */
17274
+ const ASSISTANT_PREPARATION_TOOL_CALL_NAME = 'assistant_preparation';
17275
+ /**
17276
+ * Checks whether a tool call is the assistant preparation marker.
17277
+ *
17278
+ * @public exported from `@promptbook/types`
17279
+ */
17280
+ function isAssistantPreparationToolCall(toolCall) {
17281
+ return toolCall.name === ASSISTANT_PREPARATION_TOOL_CALL_NAME;
17282
+ }
17283
+
16613
17284
  /*! *****************************************************************************
16614
17285
  Copyright (c) Microsoft Corporation.
16615
17286
 
@@ -20503,6 +21174,33 @@ const DISCRIMINANT = 'OPEN_AI_ASSISTANT_V1';
20503
21174
  * TODO: [🧠][🌰] Allow to pass `title` for tracking purposes
20504
21175
  */
20505
21176
 
21177
+ /**
21178
+ * Emits a progress update to signal assistant preparation before long setup work.
21179
+ */
21180
+ function emitAssistantPreparationProgress(options) {
21181
+ const startedAt = $getCurrentDate();
21182
+ options.onProgress({
21183
+ content: '',
21184
+ modelName: options.modelName,
21185
+ timing: {
21186
+ start: startedAt,
21187
+ complete: startedAt,
21188
+ },
21189
+ usage: UNCERTAIN_USAGE,
21190
+ rawPromptContent: options.prompt.content,
21191
+ rawRequest: null,
21192
+ rawResponse: {
21193
+ status: 'assistant_preparation',
21194
+ },
21195
+ toolCalls: [
21196
+ {
21197
+ name: ASSISTANT_PREPARATION_TOOL_CALL_NAME,
21198
+ arguments: {},
21199
+ createdAt: startedAt,
21200
+ },
21201
+ ],
21202
+ });
21203
+ }
20506
21204
  /**
20507
21205
  * Execution Tools for calling LLM models with a predefined agent "soul"
20508
21206
  * This wraps underlying LLM execution tools and applies agent-specific system prompts and requirements
@@ -20726,6 +21424,11 @@ class AgentLlmExecutionTools {
20726
21424
  if (this.options.isVerbose) {
20727
21425
  console.log(`1️⃣ Updating OpenAI Assistant for agent ${this.title}...`);
20728
21426
  }
21427
+ emitAssistantPreparationProgress({
21428
+ onProgress,
21429
+ prompt,
21430
+ modelName: this.modelName,
21431
+ });
20729
21432
  assistant = await this.options.llmTools.updateAssistant({
20730
21433
  assistantId: cached.assistantId,
20731
21434
  name: this.title,
@@ -20744,6 +21447,11 @@ class AgentLlmExecutionTools {
20744
21447
  console.log(`1️⃣ Creating new OpenAI Assistant for agent ${this.title}...`);
20745
21448
  }
20746
21449
  // <- TODO: [🐱‍🚀] Check also `isCreatingNewAssistantsAllowed` and warn about it
21450
+ emitAssistantPreparationProgress({
21451
+ onProgress,
21452
+ prompt,
21453
+ modelName: this.modelName,
21454
+ });
20747
21455
  assistant = await this.options.llmTools.createNewAssistant({
20748
21456
  name: this.title,
20749
21457
  instructions: modelRequirements.systemMessage,
@@ -21274,6 +21982,8 @@ class RemoteAgent extends Agent {
21274
21982
  // <- TODO: [🐱‍🚀] Maybe use promptbookFetch
21275
21983
  let content = '';
21276
21984
  const toolCalls = [];
21985
+ const preparationToolCalls = [];
21986
+ let hasReceivedModelOutput = false;
21277
21987
  const normalizeToolCall = (toolCall) => {
21278
21988
  if (toolCall.createdAt) {
21279
21989
  return toolCall;
@@ -21320,6 +22030,17 @@ class RemoteAgent extends Agent {
21320
22030
  const upsertToolCalls = (incomingToolCalls) => {
21321
22031
  for (const toolCall of incomingToolCalls) {
21322
22032
  const normalized = normalizeToolCall(toolCall);
22033
+ if (isAssistantPreparationToolCall(normalized)) {
22034
+ if (hasReceivedModelOutput) {
22035
+ continue;
22036
+ }
22037
+ preparationToolCalls.length = 0;
22038
+ preparationToolCalls.push(normalized);
22039
+ continue;
22040
+ }
22041
+ if (preparationToolCalls.length > 0) {
22042
+ preparationToolCalls.length = 0;
22043
+ }
21323
22044
  const key = getToolCallKey(normalized);
21324
22045
  const existingIndex = toolCalls.findIndex((existing) => getToolCallKey(existing) === key);
21325
22046
  if (existingIndex === -1) {
@@ -21330,6 +22051,10 @@ class RemoteAgent extends Agent {
21330
22051
  }
21331
22052
  }
21332
22053
  };
22054
+ /**
22055
+ * Builds the tool call list including any preparation marker still active.
22056
+ */
22057
+ const getActiveToolCalls = () => preparationToolCalls.length > 0 ? [...preparationToolCalls, ...toolCalls] : toolCalls;
21333
22058
  if (!bookResponse.body) {
21334
22059
  content = await bookResponse.text();
21335
22060
  }
@@ -21366,7 +22091,7 @@ class RemoteAgent extends Agent {
21366
22091
  rawPromptContent: {},
21367
22092
  rawRequest: {},
21368
22093
  rawResponse: {},
21369
- toolCalls: normalizedToolCalls,
22094
+ toolCalls: getActiveToolCalls(),
21370
22095
  });
21371
22096
  sawToolCalls = true;
21372
22097
  isToolCallLine = true;
@@ -21394,6 +22119,10 @@ class RemoteAgent extends Agent {
21394
22119
  // console.debug('RemoteAgent chunk:', textChunk);
21395
22120
  content += textChunk;
21396
22121
  }
22122
+ if (!hasReceivedModelOutput && content.trim().length > 0) {
22123
+ hasReceivedModelOutput = true;
22124
+ preparationToolCalls.length = 0;
22125
+ }
21397
22126
  onProgress({
21398
22127
  content,
21399
22128
  modelName: this.modelName,
@@ -21402,7 +22131,7 @@ class RemoteAgent extends Agent {
21402
22131
  rawPromptContent: {},
21403
22132
  rawRequest: {},
21404
22133
  rawResponse: {},
21405
- toolCalls,
22134
+ toolCalls: getActiveToolCalls(),
21406
22135
  });
21407
22136
  }
21408
22137
  }
@@ -21410,6 +22139,10 @@ class RemoteAgent extends Agent {
21410
22139
  const lastChunk = decoder.decode();
21411
22140
  if (lastChunk) {
21412
22141
  content += lastChunk;
22142
+ if (!hasReceivedModelOutput && content.trim().length > 0) {
22143
+ hasReceivedModelOutput = true;
22144
+ preparationToolCalls.length = 0;
22145
+ }
21413
22146
  onProgress({
21414
22147
  content: lastChunk,
21415
22148
  modelName: this.modelName,
@@ -21418,7 +22151,7 @@ class RemoteAgent extends Agent {
21418
22151
  rawPromptContent: {},
21419
22152
  rawRequest: {},
21420
22153
  rawResponse: {},
21421
- toolCalls,
22154
+ toolCalls: getActiveToolCalls(),
21422
22155
  });
21423
22156
  }
21424
22157
  }