@promptbook/fake-llm 0.66.0 → 0.67.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.
Files changed (58) hide show
  1. package/esm/index.es.js +1084 -73
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/src/_packages/core.index.d.ts +4 -4
  4. package/esm/typings/src/_packages/types.index.d.ts +7 -1
  5. package/esm/typings/src/_packages/utils.index.d.ts +14 -8
  6. package/esm/typings/src/commands/EXPECT/ExpectFormatCommand.d.ts +2 -0
  7. package/esm/typings/src/errors/{ReferenceError.d.ts → PipelineUrlError.d.ts} +2 -2
  8. package/esm/typings/src/errors/index.d.ts +27 -0
  9. package/esm/typings/src/errors/utils/ErrorJson.d.ts +20 -0
  10. package/esm/typings/src/errors/utils/deserializeError.d.ts +7 -0
  11. package/esm/typings/src/errors/utils/deserializeError.test.d.ts +1 -0
  12. package/esm/typings/src/errors/utils/serializeError.d.ts +7 -0
  13. package/esm/typings/src/errors/utils/serializeError.test.d.ts +1 -0
  14. package/esm/typings/src/execution/ExecutionTools.d.ts +4 -1
  15. package/esm/typings/src/execution/PipelineExecutor.d.ts +1 -47
  16. package/esm/typings/src/execution/PipelineExecutorResult.d.ts +49 -0
  17. package/esm/typings/src/execution/PromptResult.d.ts +5 -4
  18. package/esm/typings/src/execution/PromptResultUsage.d.ts +4 -0
  19. package/esm/typings/src/execution/UncertainNumber.d.ts +1 -0
  20. package/esm/typings/src/execution/assertsExecutionSuccessful.d.ts +2 -2
  21. package/esm/typings/src/llm-providers/_common/utils/cache/CacheItem.d.ts +0 -1
  22. package/esm/typings/src/llm-providers/mocked/$fakeTextToExpectations.d.ts +2 -2
  23. package/esm/typings/src/llm-providers/mocked/MockedFackedLlmExecutionTools.d.ts +3 -3
  24. package/esm/typings/src/llm-providers/remote/RemoteLlmExecutionTools.d.ts +1 -0
  25. package/esm/typings/src/llm-providers/remote/interfaces/PromptbookServer_Error.d.ts +2 -6
  26. package/esm/typings/src/llm-providers/remote/startRemoteServer.d.ts +1 -0
  27. package/esm/typings/src/scripting/javascript/JavascriptExecutionToolsOptions.d.ts +2 -2
  28. package/esm/typings/src/storage/_common/PromptbookStorage.d.ts +1 -1
  29. package/esm/typings/src/types/ModelRequirements.d.ts +5 -5
  30. package/esm/typings/src/types/PipelineJson/Expectations.d.ts +3 -1
  31. package/esm/typings/src/types/PipelineJson/KnowledgePieceJson.d.ts +2 -0
  32. package/esm/typings/src/types/PipelineJson/KnowledgeSourceJson.d.ts +4 -0
  33. package/esm/typings/src/types/PipelineJson/LlmTemplateJson.d.ts +2 -0
  34. package/esm/typings/src/types/PipelineJson/PersonaJson.d.ts +4 -0
  35. package/esm/typings/src/types/PipelineJson/PipelineJson.d.ts +2 -0
  36. package/esm/typings/src/types/PipelineJson/PromptDialogJson.d.ts +1 -0
  37. package/esm/typings/src/types/PipelineJson/PromptTemplateJson.d.ts +2 -0
  38. package/esm/typings/src/types/PipelineJson/PromptTemplateJsonCommon.d.ts +2 -2
  39. package/esm/typings/src/types/PipelineJson/PromptTemplateParameterJson.d.ts +2 -0
  40. package/esm/typings/src/types/PipelineJson/ScriptJson.d.ts +1 -0
  41. package/esm/typings/src/types/PipelineJson/SimpleTemplateJson.d.ts +1 -0
  42. package/esm/typings/src/types/Prompt.d.ts +7 -7
  43. package/esm/typings/src/types/ScriptLanguage.d.ts +2 -0
  44. package/esm/typings/src/types/execution-report/ExecutionPromptReportJson.d.ts +24 -0
  45. package/esm/typings/src/types/execution-report/ExecutionReportJson.d.ts +3 -20
  46. package/esm/typings/src/types/typeAliases.d.ts +7 -0
  47. package/esm/typings/src/utils/environment/$getGlobalScope.d.ts +1 -4
  48. package/esm/typings/src/utils/serialization/$asDeeplyFrozenSerializableJson.d.ts +17 -0
  49. package/esm/typings/src/utils/{deepFreeze.d.ts → serialization/$deepFreeze.d.ts} +0 -10
  50. package/esm/typings/src/utils/serialization/checkSerializableAsJson.d.ts +27 -0
  51. package/esm/typings/src/utils/{clonePipeline.d.ts → serialization/clonePipeline.d.ts} +1 -1
  52. package/esm/typings/src/utils/serialization/isSerializableAsJson.d.ts +24 -0
  53. package/esm/typings/src/utils/serialization/isSerializableAsJson.test.d.ts +1 -0
  54. package/package.json +5 -3
  55. package/umd/index.umd.js +1092 -79
  56. package/umd/index.umd.js.map +1 -1
  57. package/esm/typings/src/errors/VersionMismatchError.d.ts +0 -10
  58. /package/esm/typings/src/utils/{deepClone.d.ts → serialization/deepClone.d.ts} +0 -0
package/esm/index.es.js CHANGED
@@ -1,11 +1,14 @@
1
- import { spaceTrim } from 'spacetrim';
1
+ import _spaceTrim, { spaceTrim } from 'spacetrim';
2
2
  import { LoremIpsum } from 'lorem-ipsum';
3
+ import { format } from 'prettier';
4
+ import parserHtml from 'prettier/parser-html';
5
+ import { forTime } from 'waitasecond';
3
6
 
4
7
  // ⚠️ WARNING: This code has been generated so that any manual changes will be overwritten
5
8
  /**
6
9
  * The version of the Promptbook library
7
10
  */
8
- var PROMPTBOOK_VERSION = '0.66.0-9';
11
+ var PROMPTBOOK_VERSION = '0.66.0';
9
12
  // TODO: !!!! List here all the versions and annotate + put into script
10
13
 
11
14
  /*! *****************************************************************************
@@ -187,6 +190,165 @@ function getCurrentIsoDate() {
187
190
  return new Date().toISOString();
188
191
  }
189
192
 
193
+ /**
194
+ * This error type indicates that the error should not happen and its last check before crashing with some other error
195
+ *
196
+ * @public exported from `@promptbook/core`
197
+ */
198
+ var UnexpectedError = /** @class */ (function (_super) {
199
+ __extends(UnexpectedError, _super);
200
+ function UnexpectedError(message) {
201
+ var _this = _super.call(this, spaceTrim(function (block) { return "\n ".concat(block(message), "\n\n Note: This error should not happen.\n It's probbably a bug in the pipeline collection\n\n Please report issue:\n https://github.com/webgptorg/promptbook/issues\n\n Or contact us on me@pavolhejny.com\n\n "); })) || this;
202
+ _this.name = 'UnexpectedError';
203
+ Object.setPrototypeOf(_this, UnexpectedError.prototype);
204
+ return _this;
205
+ }
206
+ return UnexpectedError;
207
+ }(Error));
208
+
209
+ /**
210
+ * Checks if the value is [🚉] serializable as JSON
211
+ * If not, throws an UnexpectedError with a rich error message and tracking
212
+ *
213
+ * - Almost all primitives are serializable BUT:
214
+ * - `undefined` is not serializable
215
+ * - `NaN` is not serializable
216
+ * - Objects and arrays are serializable if all their properties are serializable
217
+ * - Functions are not serializable
218
+ * - Circular references are not serializable
219
+ * - `Date` objects are not serializable
220
+ * - `Map` and `Set` objects are not serializable
221
+ * - `RegExp` objects are not serializable
222
+ * - `Error` objects are not serializable
223
+ * - `Symbol` objects are not serializable
224
+ * - And much more...
225
+ *
226
+ * @throws UnexpectedError if the value is not serializable as JSON
227
+ * @public exported from `@promptbook/utils`
228
+ */
229
+ function checkSerializableAsJson(name, value) {
230
+ var e_1, _a;
231
+ if (value === undefined) {
232
+ throw new UnexpectedError("".concat(name, " is undefined"));
233
+ }
234
+ else if (value === null) {
235
+ return;
236
+ }
237
+ else if (typeof value === 'boolean') {
238
+ return;
239
+ }
240
+ else if (typeof value === 'number' && !isNaN(value)) {
241
+ return;
242
+ }
243
+ else if (typeof value === 'string') {
244
+ return;
245
+ }
246
+ else if (typeof value === 'symbol') {
247
+ throw new UnexpectedError("".concat(name, " is symbol"));
248
+ }
249
+ else if (typeof value === 'function') {
250
+ throw new UnexpectedError("".concat(name, " is function"));
251
+ }
252
+ else if (typeof value === 'object' && Array.isArray(value)) {
253
+ for (var i = 0; i < value.length; i++) {
254
+ checkSerializableAsJson("".concat(name, "[").concat(i, "]"), value[i]);
255
+ }
256
+ }
257
+ else if (typeof value === 'object') {
258
+ if (value instanceof Date) {
259
+ throw new UnexpectedError(_spaceTrim("\n ".concat(name, " is Date\n\n Use `string_date_iso8601` instead\n ")));
260
+ }
261
+ else if (value instanceof Map) {
262
+ throw new UnexpectedError("".concat(name, " is Map"));
263
+ }
264
+ else if (value instanceof Set) {
265
+ throw new UnexpectedError("".concat(name, " is Set"));
266
+ }
267
+ else if (value instanceof RegExp) {
268
+ throw new UnexpectedError("".concat(name, " is RegExp"));
269
+ }
270
+ else if (value instanceof Error) {
271
+ throw new UnexpectedError(_spaceTrim("\n ".concat(name, " is unserialized Error\n\n Use function `serializeError`\n ")));
272
+ }
273
+ else {
274
+ try {
275
+ for (var _b = __values(Object.entries(value)), _c = _b.next(); !_c.done; _c = _b.next()) {
276
+ var _d = __read(_c.value, 2), subName = _d[0], subValue = _d[1];
277
+ if (subValue === undefined) {
278
+ // Note: undefined in object is serializable - it is just omited
279
+ continue;
280
+ }
281
+ checkSerializableAsJson("".concat(name, ".").concat(subName), subValue);
282
+ }
283
+ }
284
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
285
+ finally {
286
+ try {
287
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
288
+ }
289
+ finally { if (e_1) throw e_1.error; }
290
+ }
291
+ try {
292
+ JSON.stringify(value); // <- TODO: [0]
293
+ }
294
+ catch (error) {
295
+ if (!(error instanceof Error)) {
296
+ throw error;
297
+ }
298
+ throw new UnexpectedError(_spaceTrim(function (block) { return "\n ".concat(name, " is not serializable\n\n ").concat(block(error.toString()), "\n "); }));
299
+ }
300
+ /*
301
+ TODO: [0] Is there some more elegant way to check circular references?
302
+ const seen = new Set();
303
+ const stack = [{ value }];
304
+ while (stack.length > 0) {
305
+ const { value } = stack.pop()!;
306
+ if (typeof value === 'object' && value !== null) {
307
+ if (seen.has(value)) {
308
+ throw new UnexpectedError(`${name} has circular reference`);
309
+ }
310
+ seen.add(value);
311
+ if (Array.isArray(value)) {
312
+ stack.push(...value.map((value) => ({ value })));
313
+ } else {
314
+ stack.push(...Object.values(value).map((value) => ({ value })));
315
+ }
316
+ }
317
+ }
318
+ */
319
+ return;
320
+ }
321
+ }
322
+ else {
323
+ throw new UnexpectedError("".concat(name, " is unknown"));
324
+ }
325
+ }
326
+ /**
327
+ * TODO: [🧠][🛣] More elegant way to tracking than passing `name`
328
+ * TODO: [🧠] !!! In-memory cache of same values to prevent multiple checks
329
+ * Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
330
+ */
331
+
332
+ /**
333
+ * @@@
334
+ * @@@
335
+ *
336
+ * Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
337
+ *
338
+ * @param name - Name of the object for debugging purposes
339
+ * @param objectValue - Object to be deeply frozen
340
+ * @returns The same object as the input, but deeply frozen
341
+ * @private this is in comparison to `deepFreeze` a more specific utility and maybe not very good practice to use without specific reason and considerations
342
+ */
343
+ function $asDeeplyFrozenSerializableJson(name, objectValue) {
344
+ checkSerializableAsJson(name, objectValue);
345
+ return $deepFreeze(objectValue);
346
+ }
347
+ /**
348
+ * TODO: [🧠][🛣] More elegant way to tracking than passing `name`
349
+ * TODO: [🧠] Is there a way how to meaningfully test this utility
350
+ */
351
+
190
352
  // <- TODO: [🧠] Better system for generator warnings - not always "code" and "by `@promptbook/cli`"
191
353
  /**
192
354
  * The maximum number of iterations for a loops
@@ -211,7 +373,7 @@ var REPLACING_NONCE = 'u$k42k%!V2zo34w7Fu#@QUHYPW';
211
373
  *
212
374
  * @public exported from `@promptbook/core`
213
375
  */
214
- $deepFreeze([
376
+ $asDeeplyFrozenSerializableJson('RESERVED_PARAMETER_NAMES', [
215
377
  'content',
216
378
  'context',
217
379
  'knowledge',
@@ -269,22 +431,6 @@ var PipelineExecutionError = /** @class */ (function (_super) {
269
431
  return PipelineExecutionError;
270
432
  }(Error));
271
433
 
272
- /**
273
- * This error type indicates that the error should not happen and its last check before crashing with some other error
274
- *
275
- * @public exported from `@promptbook/core`
276
- */
277
- var UnexpectedError = /** @class */ (function (_super) {
278
- __extends(UnexpectedError, _super);
279
- function UnexpectedError(message) {
280
- var _this = _super.call(this, spaceTrim(function (block) { return "\n ".concat(block(message), "\n\n Note: This error should not happen.\n It's probbably a bug in the pipeline collection\n\n Please report issue:\n https://github.com/webgptorg/promptbook/issues\n\n Or contact us on me@pavolhejny.com\n\n "); })) || this;
281
- _this.name = 'UnexpectedError';
282
- Object.setPrototypeOf(_this, UnexpectedError.prototype);
283
- return _this;
284
- }
285
- return UnexpectedError;
286
- }(Error));
287
-
288
434
  /**
289
435
  * Replaces parameters in template with values from parameters object
290
436
  *
@@ -424,7 +570,7 @@ var MockedEchoLlmExecutionTools = /** @class */ (function () {
424
570
  rawPromptContent = replaceParameters(prompt.content, __assign(__assign({}, prompt.parameters), { modelName: modelName }));
425
571
  usage = ZERO_USAGE;
426
572
  // <- TODO: [🧠] Compute here at least words, characters,... etc
427
- return [2 /*return*/, {
573
+ return [2 /*return*/, $asDeeplyFrozenSerializableJson('MockedEchoLlmExecutionTools ChatPromptResult', {
428
574
  content: spaceTrim(function (block) { return "\n You said:\n ".concat(block(rawPromptContent), "\n "); }),
429
575
  modelName: modelName,
430
576
  timing: {
@@ -438,7 +584,7 @@ var MockedEchoLlmExecutionTools = /** @class */ (function () {
438
584
  note: 'This is mocked echo',
439
585
  },
440
586
  // <- [🗯]
441
- }];
587
+ })];
442
588
  });
443
589
  });
444
590
  };
@@ -456,7 +602,7 @@ var MockedEchoLlmExecutionTools = /** @class */ (function () {
456
602
  rawPromptContent = replaceParameters(prompt.content, __assign(__assign({}, prompt.parameters), { modelName: modelName }));
457
603
  usage = ZERO_USAGE;
458
604
  // <- TODO: [🧠] Compute here at least words, characters,... etc
459
- return [2 /*return*/, {
605
+ return [2 /*return*/, $asDeeplyFrozenSerializableJson('MockedEchoLlmExecutionTools CompletionPromptResult', {
460
606
  content: spaceTrim(function (block) { return "\n ".concat(block(rawPromptContent), "\n And so on...\n "); }),
461
607
  modelName: modelName,
462
608
  timing: {
@@ -470,7 +616,7 @@ var MockedEchoLlmExecutionTools = /** @class */ (function () {
470
616
  note: 'This is mocked echo',
471
617
  },
472
618
  // <- [🗯]
473
- }];
619
+ })];
474
620
  });
475
621
  });
476
622
  };
@@ -482,86 +628,191 @@ var MockedEchoLlmExecutionTools = /** @class */ (function () {
482
628
  */
483
629
 
484
630
  /**
485
- * This error occurs when some expectation is not met in the execution of the pipeline
631
+ * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
486
632
  *
487
- * @private error of `checkExpectations` and `createPipelineExecutor`
488
- * Note: Always thrown in `checkExpectations` and catched in `createPipelineExecutor` and rethrown as `PipelineExecutionError`
489
- * Note: This is a kindof subtype of PipelineExecutionError
633
+ * @public exported from `@promptbook/core`
490
634
  */
491
- var ExpectError = /** @class */ (function (_super) {
492
- __extends(ExpectError, _super);
493
- function ExpectError(message) {
635
+ var ParsingError = /** @class */ (function (_super) {
636
+ __extends(ParsingError, _super);
637
+ function ParsingError(message) {
494
638
  var _this = _super.call(this, message) || this;
495
- _this.name = 'ExpectError';
496
- Object.setPrototypeOf(_this, ExpectError.prototype);
639
+ _this.name = 'ParsingError';
640
+ Object.setPrototypeOf(_this, ParsingError.prototype);
497
641
  return _this;
498
642
  }
499
- return ExpectError;
643
+ return ParsingError;
500
644
  }(Error));
501
645
 
502
646
  /**
503
- * Counts number of characters in the text
647
+ * Makes first letter of a string uppercase
504
648
  *
505
649
  * @public exported from `@promptbook/utils`
506
650
  */
507
- function countCharacters(text) {
508
- // Remove null characters
509
- text = text.replace(/\0/g, '');
510
- // Replace emojis (and also ZWJ sequence) with hyphens
511
- text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
512
- text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
513
- text = text.replace(/\p{Extended_Pictographic}(\u{200D}\p{Extended_Pictographic})*/gu, '-');
514
- return text.length;
651
+ function capitalize(word) {
652
+ return word.substring(0, 1).toUpperCase() + word.substring(1);
515
653
  }
516
654
 
517
655
  /**
518
- * Counts number of lines in the text
656
+ * Extracts all code blocks from markdown.
519
657
  *
520
- * @public exported from `@promptbook/utils`
658
+ * Note: There are 3 simmilar function:
659
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
660
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
661
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
662
+ *
663
+ * @param markdown any valid markdown
664
+ * @returns code blocks with language and content
665
+ * @public exported from `@promptbook/markdown-utils`
521
666
  */
522
- function countLines(text) {
523
- if (text === '') {
524
- return 0;
667
+ function extractAllBlocksFromMarkdown(markdown) {
668
+ var e_1, _a;
669
+ var codeBlocks = [];
670
+ var lines = markdown.split('\n');
671
+ // Note: [0] Ensure that the last block notated by gt > will be closed
672
+ lines.push('');
673
+ var currentCodeBlock = null;
674
+ try {
675
+ for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
676
+ var line = lines_1_1.value;
677
+ if (line.startsWith('> ') || line === '>') {
678
+ if (currentCodeBlock === null) {
679
+ currentCodeBlock = { blockNotation: '>', language: null, content: '' };
680
+ } /* not else */
681
+ if (currentCodeBlock.blockNotation === '>') {
682
+ if (currentCodeBlock.content !== '') {
683
+ currentCodeBlock.content += '\n';
684
+ }
685
+ currentCodeBlock.content += line.slice(2);
686
+ }
687
+ }
688
+ else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '>' /* <- Note: [0] */) {
689
+ codeBlocks.push(currentCodeBlock);
690
+ currentCodeBlock = null;
691
+ }
692
+ /* not else */
693
+ if (line.startsWith('```')) {
694
+ var language = line.slice(3).trim() || null;
695
+ if (currentCodeBlock === null) {
696
+ currentCodeBlock = { blockNotation: '```', language: language, content: '' };
697
+ }
698
+ else {
699
+ if (language !== null) {
700
+ throw new ParsingError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed and already opening new ").concat(language, " code block"));
701
+ }
702
+ codeBlocks.push(currentCodeBlock);
703
+ currentCodeBlock = null;
704
+ }
705
+ }
706
+ else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '```') {
707
+ if (currentCodeBlock.content !== '') {
708
+ currentCodeBlock.content += '\n';
709
+ }
710
+ currentCodeBlock.content += line.split('\\`\\`\\`').join('```') /* <- TODO: Maybe make propper unescape */;
711
+ }
712
+ }
525
713
  }
526
- return text.split('\n').length;
714
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
715
+ finally {
716
+ try {
717
+ if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
718
+ }
719
+ finally { if (e_1) throw e_1.error; }
720
+ }
721
+ if (currentCodeBlock !== null) {
722
+ throw new ParsingError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed at the end of the markdown"));
723
+ }
724
+ return codeBlocks;
527
725
  }
726
+ /**
727
+ * TODO: Maybe name for `blockNotation` instead of '```' and '>'
728
+ */
528
729
 
529
730
  /**
530
- * Counts number of pages in the text
731
+ * Extracts exactly ONE code block from markdown.
531
732
  *
532
- * @public exported from `@promptbook/utils`
733
+ * Note: If there are multiple or no code blocks the function throws an error
734
+ *
735
+ * Note: There are 3 simmilar function:
736
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
737
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
738
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
739
+ *
740
+ * @param markdown any valid markdown
741
+ * @returns code block with language and content
742
+ * @public exported from `@promptbook/markdown-utils`
533
743
  */
534
- function countPages(text) {
535
- var sentencesPerPage = 5; // Assuming each page has 5 sentences
536
- var sentences = text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
537
- var pageCount = Math.ceil(sentences.length / sentencesPerPage);
538
- return pageCount;
744
+ function extractOneBlockFromMarkdown(markdown) {
745
+ var codeBlocks = extractAllBlocksFromMarkdown(markdown);
746
+ if (codeBlocks.length !== 1) {
747
+ throw new ParsingError(_spaceTrim(function (block) { return "\n There should be exactly 1 code block, found ".concat(codeBlocks.length, " code blocks\n\n ").concat(block(codeBlocks.map(function (block, i) { return "Block ".concat(i + 1, ":\n").concat(block.content); }).join('\n\n\n')), "\n "); }));
748
+ }
749
+ return codeBlocks[0];
539
750
  }
751
+ /***
752
+ * TODO: [🍓][🌻] Decide of this is internal utility, external util OR validator/postprocessor
753
+ */
540
754
 
541
755
  /**
542
- * Counts number of paragraphs in the text
756
+ * Extracts code block from markdown.
757
+ *
758
+ * Note: If there are multiple or no code blocks the function throws an error
759
+ *
760
+ * Note: There are 3 simmilar function:
761
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
762
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
763
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
543
764
  *
544
765
  * @public exported from `@promptbook/utils`
545
766
  */
546
- function countParagraphs(text) {
547
- return text.split(/\n\s*\n/).filter(function (paragraph) { return paragraph.trim() !== ''; }).length;
767
+ function extractBlock(markdown) {
768
+ var content = extractOneBlockFromMarkdown(markdown).content;
769
+ return content;
548
770
  }
771
+ /**
772
+ * TODO: [🧠][🌻] Maybe export through `@promptbook/markdown-utils` not `@promptbook/utils`
773
+ */
549
774
 
550
775
  /**
551
- * Split text into sentences
776
+ * Prettify the html code
552
777
  *
553
- * @public exported from `@promptbook/utils`
778
+ * @param content raw html code
779
+ * @returns formatted html code
780
+ * @private withing the package because of HUGE size of prettier dependency
554
781
  */
555
- function splitIntoSentences(text) {
556
- return text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
782
+ function prettifyMarkdown(content) {
783
+ try {
784
+ return format(content, {
785
+ parser: 'markdown',
786
+ plugins: [parserHtml],
787
+ // TODO: DRY - make some import or auto-copy of .prettierrc
788
+ endOfLine: 'lf',
789
+ tabWidth: 4,
790
+ singleQuote: true,
791
+ trailingComma: 'all',
792
+ arrowParens: 'always',
793
+ printWidth: 120,
794
+ htmlWhitespaceSensitivity: 'ignore',
795
+ jsxBracketSameLine: false,
796
+ bracketSpacing: true,
797
+ });
798
+ }
799
+ catch (error) {
800
+ // TODO: [🟥] Detect browser / node and make it colorfull
801
+ console.error('There was an error with prettifying the markdown, using the original as the fallback', {
802
+ error: error,
803
+ html: content,
804
+ });
805
+ return content;
806
+ }
557
807
  }
808
+
558
809
  /**
559
- * Counts number of sentences in the text
810
+ * Makes first letter of a string uppercase
560
811
  *
561
812
  * @public exported from `@promptbook/utils`
562
813
  */
563
- function countSentences(text) {
564
- return splitIntoSentences(text).length;
814
+ function decapitalize(word) {
815
+ return word.substring(0, 1).toLowerCase() + word.substring(1);
565
816
  }
566
817
 
567
818
  var defaultDiacriticsRemovalMap = [
@@ -825,6 +1076,755 @@ function removeDiacritics(input) {
825
1076
  * TODO: [Ж] Variant for cyrillic (and in general non-latin) letters
826
1077
  */
827
1078
 
1079
+ /**
1080
+ * @@@
1081
+ *
1082
+ * @param name @@@
1083
+ * @returns @@@
1084
+ * @example @@@
1085
+ * @public exported from `@promptbook/utils`
1086
+ */
1087
+ function nameToUriPart(name) {
1088
+ var uriPart = name;
1089
+ uriPart = uriPart.toLowerCase();
1090
+ uriPart = removeDiacritics(uriPart);
1091
+ uriPart = uriPart.replace(/[^a-zA-Z0-9]+/g, '-');
1092
+ uriPart = uriPart.replace(/^-+/, '');
1093
+ uriPart = uriPart.replace(/-+$/, '');
1094
+ return uriPart;
1095
+ }
1096
+
1097
+ /**
1098
+ * @@@
1099
+ *
1100
+ * @param name @@@
1101
+ * @returns @@@
1102
+ * @example @@@
1103
+ * @public exported from `@promptbook/utils`
1104
+ */
1105
+ function nameToUriParts(name) {
1106
+ return nameToUriPart(name)
1107
+ .split('-')
1108
+ .filter(function (value) { return value !== ''; });
1109
+ }
1110
+
1111
+ /**
1112
+ * @@@
1113
+ *
1114
+ * @param text @@@
1115
+ * @returns @@@
1116
+ * @example 'hello-world'
1117
+ * @example 'i-love-promptbook'
1118
+ * @public exported from `@promptbook/utils`
1119
+ */
1120
+ function normalizeToKebabCase(text) {
1121
+ var e_1, _a;
1122
+ text = removeDiacritics(text);
1123
+ var charType;
1124
+ var lastCharType = 'OTHER';
1125
+ var normalizedName = '';
1126
+ try {
1127
+ for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
1128
+ var char = text_1_1.value;
1129
+ var normalizedChar = void 0;
1130
+ if (/^[a-z]$/.test(char)) {
1131
+ charType = 'LOWERCASE';
1132
+ normalizedChar = char;
1133
+ }
1134
+ else if (/^[A-Z]$/.test(char)) {
1135
+ charType = 'UPPERCASE';
1136
+ normalizedChar = char.toLowerCase();
1137
+ }
1138
+ else if (/^[0-9]$/.test(char)) {
1139
+ charType = 'NUMBER';
1140
+ normalizedChar = char;
1141
+ }
1142
+ else if (/^\/$/.test(char)) {
1143
+ charType = 'SLASH';
1144
+ normalizedChar = char;
1145
+ }
1146
+ else {
1147
+ charType = 'OTHER';
1148
+ normalizedChar = '-';
1149
+ }
1150
+ if (charType !== lastCharType &&
1151
+ !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
1152
+ !(lastCharType === 'NUMBER') &&
1153
+ !(charType === 'NUMBER')) {
1154
+ normalizedName += '-';
1155
+ }
1156
+ normalizedName += normalizedChar;
1157
+ lastCharType = charType;
1158
+ }
1159
+ }
1160
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
1161
+ finally {
1162
+ try {
1163
+ if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
1164
+ }
1165
+ finally { if (e_1) throw e_1.error; }
1166
+ }
1167
+ normalizedName = normalizedName.split(/-+/g).join('-');
1168
+ normalizedName = normalizedName.split(/-?\/-?/g).join('/');
1169
+ normalizedName = normalizedName.replace(/^-/, '');
1170
+ normalizedName = normalizedName.replace(/-$/, '');
1171
+ return normalizedName;
1172
+ }
1173
+
1174
+ /**
1175
+ * @@@
1176
+ *
1177
+ * @param text @@@
1178
+ * @param _isFirstLetterCapital @@@
1179
+ * @returns @@@
1180
+ * @example 'helloWorld'
1181
+ * @example 'iLovePromptbook'
1182
+ * @public exported from `@promptbook/utils`
1183
+ */
1184
+ function normalizeTo_camelCase(text, _isFirstLetterCapital) {
1185
+ var e_1, _a;
1186
+ if (_isFirstLetterCapital === void 0) { _isFirstLetterCapital = false; }
1187
+ var charType;
1188
+ var lastCharType = null;
1189
+ var normalizedName = '';
1190
+ try {
1191
+ for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
1192
+ var char = text_1_1.value;
1193
+ var normalizedChar = void 0;
1194
+ if (/^[a-z]$/.test(char)) {
1195
+ charType = 'LOWERCASE';
1196
+ normalizedChar = char;
1197
+ }
1198
+ else if (/^[A-Z]$/.test(char)) {
1199
+ charType = 'UPPERCASE';
1200
+ normalizedChar = char.toLowerCase();
1201
+ }
1202
+ else if (/^[0-9]$/.test(char)) {
1203
+ charType = 'NUMBER';
1204
+ normalizedChar = char;
1205
+ }
1206
+ else {
1207
+ charType = 'OTHER';
1208
+ normalizedChar = '';
1209
+ }
1210
+ if (!lastCharType) {
1211
+ if (_isFirstLetterCapital) {
1212
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
1213
+ }
1214
+ }
1215
+ else if (charType !== lastCharType &&
1216
+ !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
1217
+ !(lastCharType === 'NUMBER') &&
1218
+ !(charType === 'NUMBER')) {
1219
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
1220
+ }
1221
+ normalizedName += normalizedChar;
1222
+ lastCharType = charType;
1223
+ }
1224
+ }
1225
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
1226
+ finally {
1227
+ try {
1228
+ if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
1229
+ }
1230
+ finally { if (e_1) throw e_1.error; }
1231
+ }
1232
+ return normalizedName;
1233
+ }
1234
+ /**
1235
+ * TODO: [🌺] Use some intermediate util splitWords
1236
+ */
1237
+
1238
+ /**
1239
+ *
1240
+ * @param text @public exported from `@promptbook/utils`
1241
+ * @returns
1242
+ * @example 'HelloWorld'
1243
+ * @example 'ILovePromptbook'
1244
+ * @public exported from `@promptbook/utils`
1245
+ */
1246
+ function normalizeTo_PascalCase(text) {
1247
+ return normalizeTo_camelCase(text, true);
1248
+ }
1249
+
1250
+ /**
1251
+ * @@@
1252
+ *
1253
+ * @param text @@@
1254
+ * @returns @@@
1255
+ * @example 'HELLO_WORLD'
1256
+ * @example 'I_LOVE_PROMPTBOOK'
1257
+ * @public exported from `@promptbook/utils`
1258
+ */
1259
+ function normalizeTo_SCREAMING_CASE(text) {
1260
+ var e_1, _a;
1261
+ var charType;
1262
+ var lastCharType = 'OTHER';
1263
+ var normalizedName = '';
1264
+ try {
1265
+ for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
1266
+ var char = text_1_1.value;
1267
+ var normalizedChar = void 0;
1268
+ if (/^[a-z]$/.test(char)) {
1269
+ charType = 'LOWERCASE';
1270
+ normalizedChar = char.toUpperCase();
1271
+ }
1272
+ else if (/^[A-Z]$/.test(char)) {
1273
+ charType = 'UPPERCASE';
1274
+ normalizedChar = char;
1275
+ }
1276
+ else if (/^[0-9]$/.test(char)) {
1277
+ charType = 'NUMBER';
1278
+ normalizedChar = char;
1279
+ }
1280
+ else if (/^\/$/.test(char)) {
1281
+ charType = 'SLASH';
1282
+ normalizedChar = char;
1283
+ }
1284
+ else {
1285
+ charType = 'OTHER';
1286
+ normalizedChar = '_';
1287
+ }
1288
+ if (charType !== lastCharType &&
1289
+ !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
1290
+ !(lastCharType === 'NUMBER') &&
1291
+ !(charType === 'NUMBER')) {
1292
+ normalizedName += '_';
1293
+ }
1294
+ normalizedName += normalizedChar;
1295
+ lastCharType = charType;
1296
+ }
1297
+ }
1298
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
1299
+ finally {
1300
+ try {
1301
+ if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
1302
+ }
1303
+ finally { if (e_1) throw e_1.error; }
1304
+ }
1305
+ normalizedName = normalizedName.replace(/_+/g, '_');
1306
+ normalizedName = normalizedName.replace(/_?\/_?/g, '/');
1307
+ normalizedName = normalizedName.replace(/^_/, '');
1308
+ normalizedName = normalizedName.replace(/_$/, '');
1309
+ return normalizedName;
1310
+ }
1311
+ /**
1312
+ * TODO: Tests
1313
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'Moje tabule' })).toEqual('/VtG7sR9rRJqwNEdM2/Moje tabule');
1314
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'ěščřžžýáíúů' })).toEqual('/VtG7sR9rRJqwNEdM2/escrzyaieuu');
1315
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj');
1316
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj_ahojAhoj ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj-ahoj-ahoj-ahoj');
1317
+ * TODO: [🌺] Use some intermediate util splitWords
1318
+ */
1319
+
1320
+ /**
1321
+ * @@@
1322
+ *
1323
+ * @param text @@@
1324
+ * @returns @@@
1325
+ * @example 'hello_world'
1326
+ * @example 'i_love_promptbook'
1327
+ * @public exported from `@promptbook/utils`
1328
+ */
1329
+ function normalizeTo_snake_case(text) {
1330
+ return normalizeTo_SCREAMING_CASE(text).toLowerCase();
1331
+ }
1332
+
1333
+ /**
1334
+ * Take every whitespace (space, new line, tab) and replace it with a single space
1335
+ *
1336
+ * @public exported from `@promptbook/utils`
1337
+ */
1338
+ function normalizeWhitespaces(sentence) {
1339
+ return sentence.replace(/\s+/gs, ' ').trim();
1340
+ }
1341
+
1342
+ /**
1343
+ * Parses keywords from a string
1344
+ *
1345
+ * @param {string} input
1346
+ * @returns {Set} of keywords without diacritics in lowercase
1347
+ * @public exported from `@promptbook/utils`
1348
+ */
1349
+ function parseKeywordsFromString(input) {
1350
+ var keywords = normalizeTo_SCREAMING_CASE(removeDiacritics(input))
1351
+ .toLowerCase()
1352
+ .split(/[^a-z0-9]+/gs)
1353
+ .filter(function (value) { return value; });
1354
+ return new Set(keywords);
1355
+ }
1356
+
1357
+ /**
1358
+ * Removes emojis from a string and fix whitespaces
1359
+ *
1360
+ * @param text with emojis
1361
+ * @returns text without emojis
1362
+ * @public exported from `@promptbook/utils`
1363
+ */
1364
+ function removeEmojis(text) {
1365
+ // Replace emojis (and also ZWJ sequence) with hyphens
1366
+ text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
1367
+ text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
1368
+ text = text.replace(/(\p{Extended_Pictographic})(\u{200D}\p{Extended_Pictographic})*/gu, '$1');
1369
+ text = text.replace(/\p{Extended_Pictographic}/gu, '');
1370
+ return text;
1371
+ }
1372
+
1373
+ /**
1374
+ * Removes quotes from a string
1375
+ *
1376
+ * Tip: This is very usefull for post-processing of the result of the LLM model
1377
+ * Note: This function removes only the same quotes from the beginning and the end of the string
1378
+ * Note: There are two simmilar functions:
1379
+ * - `removeQuotes` which removes only bounding quotes
1380
+ * - `unwrapResult` which removes whole introduce sentence
1381
+ *
1382
+ * @param text optionally quoted text
1383
+ * @returns text without quotes
1384
+ * @public exported from `@promptbook/utils`
1385
+ */
1386
+ function removeQuotes(text) {
1387
+ if (text.startsWith('"') && text.endsWith('"')) {
1388
+ return text.slice(1, -1);
1389
+ }
1390
+ if (text.startsWith('\'') && text.endsWith('\'')) {
1391
+ return text.slice(1, -1);
1392
+ }
1393
+ return text;
1394
+ }
1395
+
1396
+ /**
1397
+ * Function trimCodeBlock will trim starting and ending code block from the string if it is present.
1398
+ *
1399
+ * Note: This is usefull for post-processing of the result of the chat LLM model
1400
+ * when the model wraps the result in the (markdown) code block.
1401
+ *
1402
+ * @public exported from `@promptbook/utils`
1403
+ */
1404
+ function trimCodeBlock(value) {
1405
+ value = spaceTrim(value);
1406
+ if (!/^```[a-z]*(.*)```$/is.test(value)) {
1407
+ return value;
1408
+ }
1409
+ value = value.replace(/^```[a-z]*/i, '');
1410
+ value = value.replace(/```$/i, '');
1411
+ value = spaceTrim(value);
1412
+ return value;
1413
+ }
1414
+
1415
+ /**
1416
+ * Function trimEndOfCodeBlock will remove ending code block from the string if it is present.
1417
+ *
1418
+ * Note: This is usefull for post-processing of the result of the completion LLM model
1419
+ * if you want to start code block in the prompt but you don't want to end it in the result.
1420
+ *
1421
+ * @public exported from `@promptbook/utils`
1422
+ */
1423
+ function trimEndOfCodeBlock(value) {
1424
+ value = spaceTrim(value);
1425
+ value = value.replace(/```$/g, '');
1426
+ value = spaceTrim(value);
1427
+ return value;
1428
+ }
1429
+
1430
+ /**
1431
+ * Removes quotes and optional introduce text from a string
1432
+ *
1433
+ * Tip: This is very usefull for post-processing of the result of the LLM model
1434
+ * Note: This function trims the text and removes whole introduce sentence if it is present
1435
+ * Note: There are two simmilar functions:
1436
+ * - `removeQuotes` which removes only bounding quotes
1437
+ * - `unwrapResult` which removes whole introduce sentence
1438
+ *
1439
+ * @param text optionally quoted text
1440
+ * @returns text without quotes
1441
+ * @public exported from `@promptbook/utils`
1442
+ */
1443
+ function unwrapResult(text, options) {
1444
+ var _a = options || {}, _b = _a.isTrimmed, isTrimmed = _b === void 0 ? true : _b, _c = _a.isIntroduceSentenceRemoved, isIntroduceSentenceRemoved = _c === void 0 ? true : _c;
1445
+ var trimmedText = text;
1446
+ // Remove leading and trailing spaces and newlines
1447
+ if (isTrimmed) {
1448
+ trimmedText = spaceTrim(trimmedText);
1449
+ }
1450
+ var processedText = trimmedText;
1451
+ if (isIntroduceSentenceRemoved) {
1452
+ var introduceSentenceRegex = /^[a-zěščřžýáíéúů:\s]*:\s*/i;
1453
+ if (introduceSentenceRegex.test(text)) {
1454
+ // Remove the introduce sentence and quotes by replacing it with an empty string
1455
+ processedText = processedText.replace(introduceSentenceRegex, '');
1456
+ }
1457
+ processedText = spaceTrim(processedText);
1458
+ }
1459
+ if (processedText.length < 3) {
1460
+ return trimmedText;
1461
+ }
1462
+ if (processedText.includes('\n')) {
1463
+ return trimmedText;
1464
+ }
1465
+ // Remove the quotes by extracting the substring without the first and last characters
1466
+ var unquotedText = processedText.slice(1, -1);
1467
+ // Check if the text starts and ends with quotes
1468
+ if ([
1469
+ ['"', '"'],
1470
+ ["'", "'"],
1471
+ ['`', '`'],
1472
+ ['*', '*'],
1473
+ ['_', '_'],
1474
+ ['„', '“'],
1475
+ ['«', '»'] /* <- QUOTES to config */,
1476
+ ].some(function (_a) {
1477
+ var _b = __read(_a, 2), startQuote = _b[0], endQuote = _b[1];
1478
+ if (!processedText.startsWith(startQuote)) {
1479
+ return false;
1480
+ }
1481
+ if (!processedText.endsWith(endQuote)) {
1482
+ return false;
1483
+ }
1484
+ if (unquotedText.includes(startQuote) && !unquotedText.includes(endQuote)) {
1485
+ return false;
1486
+ }
1487
+ if (!unquotedText.includes(startQuote) && unquotedText.includes(endQuote)) {
1488
+ return false;
1489
+ }
1490
+ return true;
1491
+ })) {
1492
+ return unwrapResult(unquotedText, { isTrimmed: false, isIntroduceSentenceRemoved: false });
1493
+ }
1494
+ else {
1495
+ return processedText;
1496
+ }
1497
+ }
1498
+ /**
1499
+ * TODO: [🧠] Should this also unwrap the (parenthesis)
1500
+ */
1501
+
1502
+ /**
1503
+ * Does nothing, but preserves the function in the bundle
1504
+ * Compiler is tricked into thinking the function is used
1505
+ *
1506
+ * @param value any function to preserve
1507
+ * @returns nothing
1508
+ * @private internal function of `JavascriptExecutionTools` and `JavascriptEvalExecutionTools`
1509
+ */
1510
+ function preserve(func) {
1511
+ // Note: NOT calling the function
1512
+ var _this = this;
1513
+ (function () { return __awaiter(_this, void 0, void 0, function () {
1514
+ return __generator(this, function (_a) {
1515
+ switch (_a.label) {
1516
+ case 0:
1517
+ // TODO: Change to `await forEver` or something better
1518
+ return [4 /*yield*/, forTime(100000000)];
1519
+ case 1:
1520
+ // TODO: Change to `await forEver` or something better
1521
+ _a.sent();
1522
+ _a.label = 2;
1523
+ case 2:
1524
+ _a.trys.push([2, , 4, 5]);
1525
+ return [4 /*yield*/, func()];
1526
+ case 3:
1527
+ _a.sent();
1528
+ return [3 /*break*/, 5];
1529
+ case 4: return [7 /*endfinally*/];
1530
+ case 5: return [2 /*return*/];
1531
+ }
1532
+ });
1533
+ }); })();
1534
+ }
1535
+ /**
1536
+ * TODO: !! [1] This maybe does memory leak
1537
+ */
1538
+
1539
+ /**
1540
+ * Converts anything to string that can be used for debugging and logging
1541
+ *
1542
+ * @param value String value for logging
1543
+ * @private internal util
1544
+ */
1545
+ function unknownToString(value) {
1546
+ if (value === undefined) {
1547
+ return 'undefined';
1548
+ }
1549
+ else if (value === null) {
1550
+ return 'null';
1551
+ }
1552
+ else if (['number', 'string', 'boolean'].includes(typeof value)) {
1553
+ return typeof value + ' ' + value.toString();
1554
+ }
1555
+ else if (typeof value === 'object' && Array.isArray(value)) {
1556
+ return 'array containing [' + value.map(function (item) { return unknownToString(item); }).join(', ') + ']';
1557
+ }
1558
+ else if (typeof value === 'object') {
1559
+ // TODO: Maybe serialize the object
1560
+ return 'object';
1561
+ }
1562
+ else {
1563
+ return 'unknown (Search in promptbook code for [🔹])';
1564
+ }
1565
+ }
1566
+
1567
+ /**
1568
+ * ScriptExecutionTools for JavaScript implemented via eval
1569
+ *
1570
+ * Warning: It is used for testing and mocking
1571
+ * **NOT intended to use in the production** due to its unsafe nature, use `JavascriptExecutionTools` instead.
1572
+ *
1573
+ * @public exported from `@promptbook/execute-javascript`
1574
+ */
1575
+ var JavascriptEvalExecutionTools = /** @class */ (function () {
1576
+ function JavascriptEvalExecutionTools(options) {
1577
+ this.options = options || {};
1578
+ }
1579
+ /**
1580
+ * Executes a JavaScript
1581
+ */
1582
+ JavascriptEvalExecutionTools.prototype.execute = function (options) {
1583
+ return __awaiter(this, void 0, void 0, function () {
1584
+ var scriptLanguage, parameters, script, spaceTrim, removeQuotes$1, unwrapResult$1, trimEndOfCodeBlock$1, trimCodeBlock$1, trim, reverse, removeEmojis$1, prettifyMarkdown$1, capitalize$1, decapitalize$1, nameToUriPart$1, nameToUriParts$1, removeDiacritics$1, normalizeWhitespaces$1, normalizeToKebabCase$1, normalizeTo_camelCase$1, normalizeTo_snake_case$1, normalizeTo_PascalCase$1, parseKeywords, normalizeTo_SCREAMING_CASE$1, buildinFunctions, buildinFunctionsStatement, customFunctions, customFunctionsStatement, statementToEvaluate, result, error_1, undefinedName_1;
1585
+ return __generator(this, function (_a) {
1586
+ switch (_a.label) {
1587
+ case 0:
1588
+ scriptLanguage = options.scriptLanguage, parameters = options.parameters;
1589
+ script = options.script;
1590
+ if (scriptLanguage !== 'javascript') {
1591
+ throw new PipelineExecutionError("Script language ".concat(scriptLanguage, " not supported to be executed by JavascriptEvalExecutionTools"));
1592
+ }
1593
+ spaceTrim = function (_) { return _spaceTrim(_); };
1594
+ preserve(spaceTrim);
1595
+ removeQuotes$1 = removeQuotes;
1596
+ preserve(removeQuotes$1);
1597
+ unwrapResult$1 = unwrapResult;
1598
+ preserve(unwrapResult$1);
1599
+ trimEndOfCodeBlock$1 = trimEndOfCodeBlock;
1600
+ preserve(trimEndOfCodeBlock$1);
1601
+ trimCodeBlock$1 = trimCodeBlock;
1602
+ preserve(trimCodeBlock$1);
1603
+ trim = function (str) { return str.trim(); };
1604
+ preserve(trim);
1605
+ reverse = function (str) { return str.split('').reverse().join(''); };
1606
+ preserve(reverse);
1607
+ removeEmojis$1 = removeEmojis;
1608
+ preserve(removeEmojis$1);
1609
+ prettifyMarkdown$1 = prettifyMarkdown;
1610
+ preserve(prettifyMarkdown$1);
1611
+ capitalize$1 = capitalize;
1612
+ decapitalize$1 = decapitalize;
1613
+ nameToUriPart$1 = nameToUriPart;
1614
+ nameToUriParts$1 = nameToUriParts;
1615
+ removeDiacritics$1 = removeDiacritics;
1616
+ normalizeWhitespaces$1 = normalizeWhitespaces;
1617
+ normalizeToKebabCase$1 = normalizeToKebabCase;
1618
+ normalizeTo_camelCase$1 = normalizeTo_camelCase;
1619
+ normalizeTo_snake_case$1 = normalizeTo_snake_case;
1620
+ normalizeTo_PascalCase$1 = normalizeTo_PascalCase;
1621
+ parseKeywords = function (input) {
1622
+ // TODO: DRY [🍯]
1623
+ return Array.from(parseKeywordsFromString(input)).join(', ');
1624
+ };
1625
+ normalizeTo_SCREAMING_CASE$1 = normalizeTo_SCREAMING_CASE;
1626
+ preserve(capitalize$1);
1627
+ preserve(decapitalize$1);
1628
+ preserve(nameToUriPart$1);
1629
+ preserve(nameToUriParts$1);
1630
+ preserve(removeDiacritics$1);
1631
+ preserve(normalizeWhitespaces$1);
1632
+ preserve(normalizeToKebabCase$1);
1633
+ preserve(normalizeTo_camelCase$1);
1634
+ preserve(normalizeTo_snake_case$1);
1635
+ preserve(normalizeTo_PascalCase$1);
1636
+ preserve(parseKeywords);
1637
+ preserve(normalizeTo_SCREAMING_CASE$1);
1638
+ //-------[/n12]---
1639
+ if (!script.includes('return')) {
1640
+ script = "return ".concat(script);
1641
+ }
1642
+ buildinFunctions = {
1643
+ // TODO: [🍯] DRY all these functions across the file
1644
+ spaceTrim: spaceTrim,
1645
+ removeQuotes: removeQuotes$1,
1646
+ unwrapResult: unwrapResult$1,
1647
+ trimEndOfCodeBlock: trimEndOfCodeBlock$1,
1648
+ trimCodeBlock: trimCodeBlock$1,
1649
+ trim: trim,
1650
+ reverse: reverse,
1651
+ removeEmojis: removeEmojis$1,
1652
+ prettifyMarkdown: prettifyMarkdown$1,
1653
+ capitalize: capitalize$1,
1654
+ decapitalize: decapitalize$1,
1655
+ nameToUriPart: nameToUriPart$1,
1656
+ nameToUriParts: nameToUriParts$1,
1657
+ removeDiacritics: removeDiacritics$1,
1658
+ normalizeWhitespaces: normalizeWhitespaces$1,
1659
+ normalizeToKebabCase: normalizeToKebabCase$1,
1660
+ normalizeTo_camelCase: normalizeTo_camelCase$1,
1661
+ normalizeTo_snake_case: normalizeTo_snake_case$1,
1662
+ normalizeTo_PascalCase: normalizeTo_PascalCase$1,
1663
+ parseKeywords: parseKeywords,
1664
+ normalizeTo_SCREAMING_CASE: normalizeTo_SCREAMING_CASE$1,
1665
+ extractBlock: extractBlock,
1666
+ };
1667
+ buildinFunctionsStatement = Object.keys(buildinFunctions)
1668
+ .map(function (functionName) {
1669
+ // Note: Custom functions are exposed to the current scope as variables
1670
+ return "const ".concat(functionName, " = buildinFunctions.").concat(functionName, ";");
1671
+ })
1672
+ .join('\n');
1673
+ customFunctions = this.options.functions || {};
1674
+ customFunctionsStatement = Object.keys(customFunctions)
1675
+ .map(function (functionName) {
1676
+ // Note: Custom functions are exposed to the current scope as variables
1677
+ return "const ".concat(functionName, " = customFunctions.").concat(functionName, ";");
1678
+ })
1679
+ .join('\n');
1680
+ statementToEvaluate = _spaceTrim(function (block) { return "\n\n // Build-in functions:\n ".concat(block(buildinFunctionsStatement), "\n\n // Custom functions:\n ").concat(block(customFunctionsStatement || '// -- No custom functions --'), "\n\n // The script:\n ").concat(block(Object.entries(parameters)
1681
+ .map(function (_a) {
1682
+ var _b = __read(_a, 2), key = _b[0], value = _b[1];
1683
+ return "const ".concat(key, " = ").concat(JSON.stringify(value), ";");
1684
+ })
1685
+ .join('\n')), "\n (()=>{ ").concat(script, " })()\n "); });
1686
+ if (this.options.isVerbose) {
1687
+ console.info(_spaceTrim(function (block) { return "\n \uD83D\uDE80 Evaluating ".concat(scriptLanguage, " script:\n\n ").concat(block(statementToEvaluate)); }));
1688
+ }
1689
+ _a.label = 1;
1690
+ case 1:
1691
+ _a.trys.push([1, 3, , 4]);
1692
+ return [4 /*yield*/, eval(statementToEvaluate)];
1693
+ case 2:
1694
+ result = _a.sent();
1695
+ if (typeof result !== 'string') {
1696
+ throw new PipelineExecutionError("Script must return a string, but returned ".concat(unknownToString(result)));
1697
+ }
1698
+ return [3 /*break*/, 4];
1699
+ case 3:
1700
+ error_1 = _a.sent();
1701
+ if (!(error_1 instanceof Error)) {
1702
+ throw error_1;
1703
+ }
1704
+ if (error_1 instanceof ReferenceError) {
1705
+ undefinedName_1 = error_1.message.split(' ')[0];
1706
+ /*
1707
+ Note: Remapping error
1708
+ From: [PipelineUrlError: thing is not defined],
1709
+ To: [PipelineExecutionError: Parameter {thing} is not defined],
1710
+ */
1711
+ if (!statementToEvaluate.includes(undefinedName_1 + '(')) {
1712
+ throw new PipelineExecutionError(_spaceTrim(function (block) { return "\n\n Parameter {".concat(undefinedName_1, "} is not defined\n\n This happen during evaluation of the javascript, which has access to the following parameters as javascript variables:\n\n ").concat(block(Object.keys(parameters)
1713
+ .map(function (key) { return " - ".concat(key, "\n"); })
1714
+ .join('')), "\n\n The script is:\n ```javascript\n ").concat(block(script), "\n ```\n\n Original error message:\n ").concat(block(error_1.message), "\n\n\n "); }));
1715
+ }
1716
+ else {
1717
+ throw new PipelineExecutionError(_spaceTrim(function (block) { return "\n Function ".concat(undefinedName_1, "() is not defined\n\n - Make sure that the function is one of built-in functions\n - Or you have to defined the function during construction of JavascriptEvalExecutionTools\n\n Original error message:\n ").concat(block(error_1.message), "\n\n "); }));
1718
+ }
1719
+ }
1720
+ throw error_1;
1721
+ case 4:
1722
+ if (typeof result !== 'string') {
1723
+ throw new PipelineExecutionError("Script must return a string, but ".concat(unknownToString(result)));
1724
+ }
1725
+ return [2 /*return*/, result];
1726
+ }
1727
+ });
1728
+ });
1729
+ };
1730
+ return JavascriptEvalExecutionTools;
1731
+ }());
1732
+ /**
1733
+ * TODO: Put predefined functions (like removeQuotes, spaceTrim, etc.) into annotation OR pass into constructor
1734
+ * TODO: [🧠][💙] Distinct between options passed into ExecutionTools and to ExecutionTools.execute
1735
+ */
1736
+
1737
+ /**
1738
+ * Placeholder for better implementation of JavascriptExecutionTools - some propper sandboxing
1739
+ *
1740
+ * @alias JavascriptExecutionTools
1741
+ * @public exported from `@promptbook/execute-javascript`
1742
+ */
1743
+ var JavascriptExecutionTools = JavascriptEvalExecutionTools;
1744
+
1745
+ /**
1746
+ * This error occurs when some expectation is not met in the execution of the pipeline
1747
+ *
1748
+ * @private error of `checkExpectations` and `createPipelineExecutor`
1749
+ * Note: Always thrown in `checkExpectations` and catched in `createPipelineExecutor` and rethrown as `PipelineExecutionError`
1750
+ * Note: This is a kindof subtype of PipelineExecutionError
1751
+ */
1752
+ var ExpectError = /** @class */ (function (_super) {
1753
+ __extends(ExpectError, _super);
1754
+ function ExpectError(message) {
1755
+ var _this = _super.call(this, message) || this;
1756
+ _this.name = 'ExpectError';
1757
+ Object.setPrototypeOf(_this, ExpectError.prototype);
1758
+ return _this;
1759
+ }
1760
+ return ExpectError;
1761
+ }(Error));
1762
+
1763
+ /**
1764
+ * Counts number of characters in the text
1765
+ *
1766
+ * @public exported from `@promptbook/utils`
1767
+ */
1768
+ function countCharacters(text) {
1769
+ // Remove null characters
1770
+ text = text.replace(/\0/g, '');
1771
+ // Replace emojis (and also ZWJ sequence) with hyphens
1772
+ text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
1773
+ text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
1774
+ text = text.replace(/\p{Extended_Pictographic}(\u{200D}\p{Extended_Pictographic})*/gu, '-');
1775
+ return text.length;
1776
+ }
1777
+
1778
+ /**
1779
+ * Counts number of lines in the text
1780
+ *
1781
+ * @public exported from `@promptbook/utils`
1782
+ */
1783
+ function countLines(text) {
1784
+ if (text === '') {
1785
+ return 0;
1786
+ }
1787
+ return text.split('\n').length;
1788
+ }
1789
+
1790
+ /**
1791
+ * Counts number of pages in the text
1792
+ *
1793
+ * @public exported from `@promptbook/utils`
1794
+ */
1795
+ function countPages(text) {
1796
+ var sentencesPerPage = 5; // Assuming each page has 5 sentences
1797
+ var sentences = text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
1798
+ var pageCount = Math.ceil(sentences.length / sentencesPerPage);
1799
+ return pageCount;
1800
+ }
1801
+
1802
+ /**
1803
+ * Counts number of paragraphs in the text
1804
+ *
1805
+ * @public exported from `@promptbook/utils`
1806
+ */
1807
+ function countParagraphs(text) {
1808
+ return text.split(/\n\s*\n/).filter(function (paragraph) { return paragraph.trim() !== ''; }).length;
1809
+ }
1810
+
1811
+ /**
1812
+ * Split text into sentences
1813
+ *
1814
+ * @public exported from `@promptbook/utils`
1815
+ */
1816
+ function splitIntoSentences(text) {
1817
+ return text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
1818
+ }
1819
+ /**
1820
+ * Counts number of sentences in the text
1821
+ *
1822
+ * @public exported from `@promptbook/utils`
1823
+ */
1824
+ function countSentences(text) {
1825
+ return splitIntoSentences(text).length;
1826
+ }
1827
+
828
1828
  /**
829
1829
  * Counts number of words in the text
830
1830
  *
@@ -918,9 +1918,9 @@ function isPassingExpectations(expectations, value) {
918
1918
  *
919
1919
  * @private internal utility for MockedFackedLlmExecutionTools
920
1920
  */
921
- function $fakeTextToExpectations(expectations, postprocessing) {
1921
+ function $fakeTextToExpectations(expectations, postprocessingFunctionNames) {
922
1922
  return __awaiter(this, void 0, void 0, function () {
923
- var lorem, loremText, text, loopLimit, textToCheck, _a, _b, func, e_1_1;
1923
+ var lorem, loremText, text, loopLimit, textToCheck, scriptTools, _a, _b, postprocessingFunctionName, e_1_1;
924
1924
  var e_1, _c;
925
1925
  return __generator(this, function (_d) {
926
1926
  switch (_d.label) {
@@ -938,15 +1938,26 @@ function $fakeTextToExpectations(expectations, postprocessing) {
938
1938
  case 1:
939
1939
  if (!(loopLimit-- > 0)) return [3 /*break*/, 11];
940
1940
  textToCheck = text;
1941
+ scriptTools = null;
941
1942
  _d.label = 2;
942
1943
  case 2:
943
1944
  _d.trys.push([2, 7, 8, 9]);
944
- _a = (e_1 = void 0, __values(postprocessing || [])), _b = _a.next();
1945
+ _a = (e_1 = void 0, __values(postprocessingFunctionNames || [])), _b = _a.next();
945
1946
  _d.label = 3;
946
1947
  case 3:
947
1948
  if (!!_b.done) return [3 /*break*/, 6];
948
- func = _b.value;
949
- return [4 /*yield*/, func(textToCheck)];
1949
+ postprocessingFunctionName = _b.value;
1950
+ if (scriptTools === null) {
1951
+ scriptTools = new JavascriptExecutionTools();
1952
+ }
1953
+ return [4 /*yield*/, scriptTools.execute({
1954
+ scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
1955
+ script: "".concat(postprocessingFunctionName, "(result)"),
1956
+ parameters: {
1957
+ result: textToCheck || '',
1958
+ // Note: No ...parametersForTemplate, because working with result only
1959
+ },
1960
+ })];
950
1961
  case 4:
951
1962
  textToCheck = _d.sent();
952
1963
  _d.label = 5;
@@ -1047,7 +2058,7 @@ var MockedFackedLlmExecutionTools = /** @class */ (function () {
1047
2058
  usage = ZERO_USAGE;
1048
2059
  return [4 /*yield*/, $fakeTextToExpectations(prompt.expectations || {
1049
2060
  sentences: { min: 1, max: 1 },
1050
- }, prompt.postprocessing)];
2061
+ }, prompt.postprocessingFunctionNames)];
1051
2062
  case 1:
1052
2063
  content = _a.sent();
1053
2064
  result = {
@@ -1068,7 +2079,7 @@ var MockedFackedLlmExecutionTools = /** @class */ (function () {
1068
2079
  if (this.options.isVerbose) {
1069
2080
  console.info('💬 Mocked faked result', result);
1070
2081
  }
1071
- return [2 /*return*/, result];
2082
+ return [2 /*return*/, $asDeeplyFrozenSerializableJson('MockedFackedLlmExecutionTools (ChatPromptResult or CompletionPromptResult)', result)];
1072
2083
  }
1073
2084
  });
1074
2085
  });
@@ -1116,7 +2127,7 @@ var MockedFackedLlmExecutionTools = /** @class */ (function () {
1116
2127
  if (this.options.isVerbose) {
1117
2128
  console.info('💬 Mocked faked result', result);
1118
2129
  }
1119
- return [2 /*return*/, result];
2130
+ return [2 /*return*/, $asDeeplyFrozenSerializableJson('MockedFackedLlmExecutionTools EmbeddingPromptResult', result)];
1120
2131
  });
1121
2132
  });
1122
2133
  };