@promptbook/core 0.72.0-8 → 0.72.0-9

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 (118) hide show
  1. package/README.md +4 -0
  2. package/esm/index.es.js +1624 -2222
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/src/_packages/browser.index.d.ts +2 -0
  5. package/esm/typings/src/_packages/cli.index.d.ts +20 -0
  6. package/esm/typings/src/_packages/core.index.d.ts +20 -14
  7. package/esm/typings/src/_packages/documents.index.d.ts +8 -0
  8. package/esm/typings/src/_packages/legacy-documents.index.d.ts +8 -0
  9. package/esm/typings/src/_packages/markdown-utils.index.d.ts +6 -0
  10. package/esm/typings/src/_packages/node.index.d.ts +10 -4
  11. package/esm/typings/src/_packages/pdf.index.d.ts +8 -0
  12. package/esm/typings/src/_packages/types.index.d.ts +15 -5
  13. package/esm/typings/src/_packages/website-crawler.index.d.ts +8 -0
  14. package/esm/typings/src/collection/constructors/createCollectionFromDirectory.d.ts +5 -3
  15. package/esm/typings/src/config.d.ts +6 -0
  16. package/esm/typings/src/conversion/pipelineStringToJson.d.ts +3 -1
  17. package/esm/typings/src/dialogs/callback/CallbackInterfaceToolsOptions.d.ts +2 -2
  18. package/esm/typings/src/dialogs/simple-prompt/SimplePromptInterfaceTools.d.ts +3 -3
  19. package/esm/typings/src/execution/{CommonExecutionToolsOptions.d.ts → CommonToolsOptions.d.ts} +1 -1
  20. package/esm/typings/src/execution/ExecutionTools.d.ts +26 -6
  21. package/esm/typings/src/execution/FilesystemTools.d.ts +9 -0
  22. package/esm/typings/src/execution/createPipelineExecutor/10-executePipeline.d.ts +1 -1
  23. package/esm/typings/src/execution/createPipelineExecutor/20-executeTemplate.d.ts +1 -6
  24. package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempts.d.ts +1 -6
  25. package/esm/typings/src/execution/translation/automatic-translate/translateMessages.d.ts +1 -0
  26. package/esm/typings/src/execution/utils/$provideExecutionToolsForNode.d.ts +13 -0
  27. package/esm/typings/src/llm-providers/_common/{$llmToolsMetadataRegister.d.ts → register/$llmToolsMetadataRegister.d.ts} +4 -1
  28. package/esm/typings/src/llm-providers/_common/{$llmToolsRegister.d.ts → register/$llmToolsRegister.d.ts} +5 -2
  29. package/esm/typings/src/llm-providers/_common/{createLlmToolsFromConfigurationFromEnv.d.ts → register/$provideLlmToolsConfigurationFromEnv.d.ts} +3 -3
  30. package/esm/typings/src/llm-providers/_common/{getLlmToolsForCli.d.ts → register/$provideLlmToolsForCli.d.ts} +4 -11
  31. package/esm/typings/src/llm-providers/_common/{getLlmToolsForTestingAndScriptsAndPlayground.d.ts → register/$provideLlmToolsForTestingAndScriptsAndPlayground.d.ts} +4 -3
  32. package/esm/typings/src/llm-providers/_common/{createLlmToolsFromEnv.d.ts → register/$provideLlmToolsFromEnv.d.ts} +6 -5
  33. package/esm/typings/src/llm-providers/_common/{$registeredLlmToolsMessage.d.ts → register/$registeredLlmToolsMessage.d.ts} +5 -2
  34. package/esm/typings/src/llm-providers/_common/{LlmToolsConfiguration.d.ts → register/LlmToolsConfiguration.d.ts} +5 -4
  35. package/esm/typings/src/llm-providers/_common/{LlmToolsMetadata.d.ts → register/LlmToolsMetadata.d.ts} +5 -4
  36. package/esm/typings/src/llm-providers/_common/{LlmToolsOptions.d.ts → register/LlmToolsOptions.d.ts} +4 -1
  37. package/esm/typings/src/llm-providers/_common/{createLlmToolsFromConfiguration.d.ts → register/createLlmToolsFromConfiguration.d.ts} +5 -4
  38. package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionToolsOptions.d.ts +3 -3
  39. package/esm/typings/src/llm-providers/anthropic-claude/register-configuration.d.ts +4 -3
  40. package/esm/typings/src/llm-providers/anthropic-claude/register-constructor.d.ts +4 -3
  41. package/esm/typings/src/llm-providers/azure-openai/AzureOpenAiExecutionToolsOptions.d.ts +2 -2
  42. package/esm/typings/src/llm-providers/azure-openai/register-configuration.d.ts +4 -3
  43. package/esm/typings/src/llm-providers/azure-openai/register-constructor.d.ts +4 -3
  44. package/esm/typings/src/llm-providers/mocked/MockedEchoLlmExecutionTools.d.ts +3 -3
  45. package/esm/typings/src/llm-providers/mocked/MockedFackedLlmExecutionTools.d.ts +3 -3
  46. package/esm/typings/src/llm-providers/multiple/MultipleLlmExecutionTools.d.ts +1 -0
  47. package/esm/typings/src/llm-providers/openai/OpenAiExecutionToolsOptions.d.ts +2 -2
  48. package/esm/typings/src/llm-providers/openai/register-configuration.d.ts +5 -4
  49. package/esm/typings/src/llm-providers/openai/register-constructor.d.ts +5 -4
  50. package/esm/typings/src/llm-providers/remote/interfaces/PromptbookServer_ListModels_Request.d.ts +1 -1
  51. package/esm/typings/src/llm-providers/remote/interfaces/PromptbookServer_Prompt_Request.d.ts +1 -1
  52. package/esm/typings/src/llm-providers/remote/interfaces/RemoteLlmExecutionToolsOptions.d.ts +3 -3
  53. package/esm/typings/src/llm-providers/remote/interfaces/RemoteServerOptions.d.ts +2 -2
  54. package/esm/typings/src/personas/preparePersona.d.ts +2 -1
  55. package/esm/typings/src/prepare/PrepareAndScrapeOptions.d.ts +8 -7
  56. package/esm/typings/src/prepare/preparePipeline.d.ts +2 -1
  57. package/esm/typings/src/prepare/prepareTemplates.d.ts +2 -1
  58. package/esm/typings/src/scrapers/_common/Converter.d.ts +4 -10
  59. package/esm/typings/src/scrapers/_common/Scraper.d.ts +4 -9
  60. package/esm/typings/src/scrapers/_common/prepareKnowledgePieces.d.ts +2 -1
  61. package/esm/typings/src/scrapers/_common/register/$provideFilesystemForNode.d.ts +11 -0
  62. package/esm/typings/src/scrapers/_common/register/$provideScrapersForBrowser.d.ts +12 -0
  63. package/esm/typings/src/scrapers/_common/register/$provideScrapersForNode.d.ts +15 -0
  64. package/esm/typings/src/scrapers/_common/register/$registeredScrapersMessage.d.ts +12 -0
  65. package/esm/typings/src/scrapers/_common/register/$scrapersMetadataRegister.d.ts +13 -0
  66. package/esm/typings/src/scrapers/_common/register/$scrapersRegister.d.ts +13 -0
  67. package/esm/typings/src/scrapers/_common/register/ScraperAndConverterMetadata.d.ts +41 -0
  68. package/esm/typings/src/scrapers/_common/register/ScraperConstructor.d.ts +12 -0
  69. package/esm/typings/src/scrapers/_common/utils/getScraperIntermediateSource.d.ts +1 -0
  70. package/esm/typings/src/scrapers/_common/utils/makeKnowledgeSourceHandler.d.ts +2 -1
  71. package/esm/typings/src/scrapers/document/{documentScraper.d.ts → DocumentScraper.d.ts} +18 -12
  72. package/esm/typings/src/scrapers/document/createDocumentScraper.d.ts +20 -0
  73. package/esm/typings/src/scrapers/document/register-constructor.d.ts +13 -0
  74. package/esm/typings/src/scrapers/document/register-metadata.d.ts +24 -0
  75. package/esm/typings/src/scrapers/document-legacy/{legacyDocumentScraper.d.ts → LegacyDocumentScraper.d.ts} +18 -12
  76. package/esm/typings/src/scrapers/document-legacy/createLegacyDocumentScraper.d.ts +20 -0
  77. package/esm/typings/src/scrapers/document-legacy/register-constructor.d.ts +13 -0
  78. package/esm/typings/src/scrapers/document-legacy/register-metadata.d.ts +24 -0
  79. package/esm/typings/src/scrapers/markdown/MarkdownScraper.d.ts +29 -0
  80. package/esm/typings/src/scrapers/markdown/createMarkdownScraper.d.ts +20 -0
  81. package/esm/typings/src/scrapers/markdown/register-constructor.d.ts +13 -0
  82. package/esm/typings/src/scrapers/markdown/register-metadata.d.ts +24 -0
  83. package/esm/typings/src/scrapers/pdf/PdfScraper.d.ts +40 -0
  84. package/esm/typings/src/scrapers/pdf/createPdfScraper.d.ts +20 -0
  85. package/esm/typings/src/scrapers/pdf/register-constructor.d.ts +13 -0
  86. package/esm/typings/src/scrapers/pdf/register-metadata.d.ts +24 -0
  87. package/esm/typings/src/scrapers/website/{websiteScraper.d.ts → WebsiteScraper.d.ts} +18 -14
  88. package/esm/typings/src/scrapers/website/createWebsiteScraper.d.ts +20 -0
  89. package/esm/typings/src/scrapers/website/register-constructor.d.ts +13 -0
  90. package/esm/typings/src/scrapers/website/register-metadata.d.ts +24 -0
  91. package/esm/typings/src/scripting/javascript/JavascriptExecutionToolsOptions.d.ts +2 -2
  92. package/esm/typings/src/scripting/python/PythonExecutionTools.d.ts +3 -3
  93. package/esm/typings/src/scripting/typescript/TypescriptExecutionTools.d.ts +3 -3
  94. package/esm/typings/src/storage/file-cache-storage/FileCacheStorage.d.ts +5 -3
  95. package/esm/typings/src/storage/{utils → memory/utils}/PrefixStorage.d.ts +1 -1
  96. package/esm/typings/src/storage/{utils → memory/utils}/makePromptbookStorageFromWebStorage.d.ts +1 -1
  97. package/esm/typings/src/types/typeAliases.d.ts +7 -0
  98. package/esm/typings/src/utils/$Register.d.ts +19 -6
  99. package/esm/typings/src/utils/execCommand/$execCommand.d.ts +1 -1
  100. package/esm/typings/src/utils/execCommand/$execCommands.d.ts +1 -1
  101. package/esm/typings/src/utils/files/isDirectoryExisting.d.ts +14 -0
  102. package/esm/typings/src/utils/files/isFileExisting.d.ts +13 -0
  103. package/esm/typings/src/utils/files/{$listAllFiles.d.ts → listAllFiles.d.ts} +3 -4
  104. package/package.json +1 -5
  105. package/umd/index.umd.js +1633 -2223
  106. package/umd/index.umd.js.map +1 -1
  107. package/esm/typings/src/scrapers/index.d.ts +0 -8
  108. package/esm/typings/src/scrapers/markdown/markdownScraper.d.ts +0 -29
  109. package/esm/typings/src/scrapers/pdf/pdfScraper.d.ts +0 -35
  110. package/esm/typings/src/utils/files/$isDirectoryExisting.d.ts +0 -15
  111. package/esm/typings/src/utils/files/$isFileExisting.d.ts +0 -14
  112. /package/esm/typings/src/scrapers/document/{documentScraper.test.d.ts → DocumentScraper.test.d.ts} +0 -0
  113. /package/esm/typings/src/scrapers/document-legacy/{legacyDocumentScraper.test.d.ts → LegacyDocumentScraper.test.d.ts} +0 -0
  114. /package/esm/typings/src/scrapers/markdown/{markdownScraper.test.d.ts → MarkdownScraper.test.d.ts} +0 -0
  115. /package/esm/typings/src/scrapers/website/{websiteScraper.test.d.ts → WebsiteScraper.test.d.ts} +0 -0
  116. /package/esm/typings/src/utils/files/{$isDirectoryExisting.test.d.ts → isDirectoryExisting.test.d.ts} +0 -0
  117. /package/esm/typings/src/utils/files/{$isFileExisting.test.d.ts → isFileExisting.test.d.ts} +0 -0
  118. /package/esm/typings/src/utils/files/{$listAllFiles.test.d.ts → listAllFiles.test.d.ts} +0 -0
package/esm/index.es.js CHANGED
@@ -1,17 +1,11 @@
1
1
  import spaceTrim, { spaceTrim as spaceTrim$1 } from 'spacetrim';
2
2
  import { format } from 'prettier';
3
3
  import parserHtml from 'prettier/parser-html';
4
- import { stat, access, constants, mkdir, rm, readFile, rmdir, rename, readdir, writeFile } from 'fs/promises';
5
- import { basename, join, dirname } from 'path';
6
- import { spawn } from 'child_process';
7
- import colors from 'colors';
8
4
  import { forTime } from 'waitasecond';
5
+ import { unparse, parse } from 'papaparse';
6
+ import { join, basename } from 'path';
9
7
  import { SHA256 } from 'crypto-js';
10
8
  import hexEncoder from 'crypto-js/enc-hex';
11
- import { unparse, parse } from 'papaparse';
12
- import { Readability } from '@mozilla/readability';
13
- import { JSDOM } from 'jsdom';
14
- import { Converter } from 'showdown';
15
9
  import { lookup } from 'mime-types';
16
10
  import sha256 from 'crypto-js/sha256';
17
11
  import moment from 'moment';
@@ -20,7 +14,7 @@ import moment from 'moment';
20
14
  /**
21
15
  * The version of the Promptbook library
22
16
  */
23
- var PROMPTBOOK_VERSION = '0.72.0-7';
17
+ var PROMPTBOOK_VERSION = '0.72.0-8';
24
18
  // TODO: [main] !!!! List here all the versions and annotate + put into script
25
19
 
26
20
  /*! *****************************************************************************
@@ -784,6 +778,12 @@ var DEFAULT_CSV_SETTINGS = Object.freeze({
784
778
  * @public exported from `@promptbook/core`
785
779
  */
786
780
  var IS_VERBOSE = false;
781
+ /**
782
+ * @@@
783
+ *
784
+ * @public exported from `@promptbook/core`
785
+ */
786
+ var IS_AUTO_INSTALLED = false;
787
787
  /**
788
788
  * @@@
789
789
  *
@@ -1654,19 +1654,19 @@ var TemplateTypes = [
1654
1654
  ];
1655
1655
 
1656
1656
  /**
1657
- * This error indicates that the promptbook can not retrieve knowledge from external sources
1657
+ * This error type indicates that some tools are missing for pipeline execution or preparation
1658
1658
  *
1659
1659
  * @public exported from `@promptbook/core`
1660
1660
  */
1661
- var KnowledgeScrapeError = /** @class */ (function (_super) {
1662
- __extends(KnowledgeScrapeError, _super);
1663
- function KnowledgeScrapeError(message) {
1664
- var _this = _super.call(this, message) || this;
1665
- _this.name = 'KnowledgeScrapeError';
1666
- Object.setPrototypeOf(_this, KnowledgeScrapeError.prototype);
1661
+ var MissingToolsError = /** @class */ (function (_super) {
1662
+ __extends(MissingToolsError, _super);
1663
+ function MissingToolsError(message) {
1664
+ var _this = _super.call(this, spaceTrim$1(function (block) { return "\n ".concat(block(message), "\n\n Note: You have probbably forgot to provide some tools for pipeline execution or preparation\n\n "); })) || this;
1665
+ _this.name = 'MissingToolsError';
1666
+ Object.setPrototypeOf(_this, MissingToolsError.prototype);
1667
1667
  return _this;
1668
1668
  }
1669
- return KnowledgeScrapeError;
1669
+ return MissingToolsError;
1670
1670
  }(Error));
1671
1671
 
1672
1672
  /**
@@ -1746,1042 +1746,188 @@ function forEachAsync(array, options, callbackfunction) {
1746
1746
  }
1747
1747
 
1748
1748
  /**
1749
- * This error type indicates that some tools are missing for pipeline execution or preparation
1749
+ * Represents the usage with no resources consumed
1750
1750
  *
1751
1751
  * @public exported from `@promptbook/core`
1752
1752
  */
1753
- var MissingToolsError = /** @class */ (function (_super) {
1754
- __extends(MissingToolsError, _super);
1755
- function MissingToolsError(message) {
1756
- var _this = _super.call(this, spaceTrim$1(function (block) { return "\n ".concat(block(message), "\n\n Note: You have probbably forgot to provide some tools for pipeline execution or preparation\n\n "); })) || this;
1757
- _this.name = 'MissingToolsError';
1758
- Object.setPrototypeOf(_this, MissingToolsError.prototype);
1759
- return _this;
1760
- }
1761
- return MissingToolsError;
1762
- }(Error));
1763
-
1753
+ var ZERO_USAGE = $deepFreeze({
1754
+ price: { value: 0 },
1755
+ input: {
1756
+ tokensCount: { value: 0 },
1757
+ charactersCount: { value: 0 },
1758
+ wordsCount: { value: 0 },
1759
+ sentencesCount: { value: 0 },
1760
+ linesCount: { value: 0 },
1761
+ paragraphsCount: { value: 0 },
1762
+ pagesCount: { value: 0 },
1763
+ },
1764
+ output: {
1765
+ tokensCount: { value: 0 },
1766
+ charactersCount: { value: 0 },
1767
+ wordsCount: { value: 0 },
1768
+ sentencesCount: { value: 0 },
1769
+ linesCount: { value: 0 },
1770
+ paragraphsCount: { value: 0 },
1771
+ pagesCount: { value: 0 },
1772
+ },
1773
+ });
1764
1774
  /**
1765
- * Detects if the code is running in a Node.js environment
1766
- *
1767
- * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
1775
+ * Represents the usage with unknown resources consumed
1768
1776
  *
1769
- * @public exported from `@promptbook/utils`
1777
+ * @public exported from `@promptbook/core`
1770
1778
  */
1771
- var $isRunningInNode = new Function("\n try {\n return this === global;\n } catch (e) {\n return false;\n }\n");
1779
+ var UNCERTAIN_USAGE = $deepFreeze({
1780
+ price: { value: 0, isUncertain: true },
1781
+ input: {
1782
+ tokensCount: { value: 0, isUncertain: true },
1783
+ charactersCount: { value: 0, isUncertain: true },
1784
+ wordsCount: { value: 0, isUncertain: true },
1785
+ sentencesCount: { value: 0, isUncertain: true },
1786
+ linesCount: { value: 0, isUncertain: true },
1787
+ paragraphsCount: { value: 0, isUncertain: true },
1788
+ pagesCount: { value: 0, isUncertain: true },
1789
+ },
1790
+ output: {
1791
+ tokensCount: { value: 0, isUncertain: true },
1792
+ charactersCount: { value: 0, isUncertain: true },
1793
+ wordsCount: { value: 0, isUncertain: true },
1794
+ sentencesCount: { value: 0, isUncertain: true },
1795
+ linesCount: { value: 0, isUncertain: true },
1796
+ paragraphsCount: { value: 0, isUncertain: true },
1797
+ pagesCount: { value: 0, isUncertain: true },
1798
+ },
1799
+ });
1772
1800
 
1773
1801
  /**
1774
- * This error type indicates that you try to use a feature that is not available in the current environment
1802
+ * This error indicates errors during the execution of the pipeline
1775
1803
  *
1776
1804
  * @public exported from `@promptbook/core`
1777
1805
  */
1778
- var EnvironmentMismatchError = /** @class */ (function (_super) {
1779
- __extends(EnvironmentMismatchError, _super);
1780
- function EnvironmentMismatchError(message) {
1806
+ var PipelineExecutionError = /** @class */ (function (_super) {
1807
+ __extends(PipelineExecutionError, _super);
1808
+ function PipelineExecutionError(message) {
1781
1809
  var _this = _super.call(this, message) || this;
1782
- _this.name = 'EnvironmentMismatchError';
1783
- Object.setPrototypeOf(_this, EnvironmentMismatchError.prototype);
1810
+ _this.name = 'PipelineExecutionError';
1811
+ Object.setPrototypeOf(_this, PipelineExecutionError.prototype);
1784
1812
  return _this;
1785
1813
  }
1786
- return EnvironmentMismatchError;
1814
+ return PipelineExecutionError;
1787
1815
  }(Error));
1788
1816
 
1789
1817
  /**
1790
- * Normalize options for `execCommand` and `execCommands`
1818
+ * Multiple LLM Execution Tools is a proxy server that uses multiple execution tools internally and exposes the executor interface externally.
1791
1819
  *
1792
- * @private internal utility of `execCommand` and `execCommands`
1820
+ * Note: Internal utility of `joinLlmExecutionTools` but exposed type
1821
+ * @public exported from `@promptbook/types`
1822
+ * TODO: !!!!!! Export as runtime class not just type
1793
1823
  */
1794
- function execCommandNormalizeOptions(options) {
1795
- var _a;
1796
- var _b, _c, _d;
1797
- var command;
1798
- var cwd;
1799
- var crashOnError;
1800
- var args = [];
1801
- var timeout;
1802
- if (typeof options === 'string') {
1803
- // TODO: [1] DRY default values
1804
- command = options;
1805
- cwd = process.cwd();
1806
- crashOnError = true;
1807
- timeout = Infinity;
1808
- }
1809
- else {
1810
- /*
1811
- TODO:
1812
- if ((options as any).commands !== undefined) {
1813
- commands = (options as any).commands;
1814
- } else {
1815
- commands = [(options as any).command];
1824
+ var MultipleLlmExecutionTools = /** @class */ (function () {
1825
+ /**
1826
+ * Gets array of execution tools in order of priority
1827
+ */
1828
+ function MultipleLlmExecutionTools() {
1829
+ var llmExecutionTools = [];
1830
+ for (var _i = 0; _i < arguments.length; _i++) {
1831
+ llmExecutionTools[_i] = arguments[_i];
1816
1832
  }
1817
- */
1818
- // TODO: [1] DRY default values
1819
- command = options.command;
1820
- cwd = (_b = options.cwd) !== null && _b !== void 0 ? _b : process.cwd();
1821
- crashOnError = (_c = options.crashOnError) !== null && _c !== void 0 ? _c : true;
1822
- timeout = (_d = options.timeout) !== null && _d !== void 0 ? _d : Infinity;
1823
- }
1824
- // TODO: /(-[a-zA-Z0-9-]+\s+[^\s]*)|[^\s]*/g
1825
- var _ = Array.from(command.matchAll(/(".*")|([^\s]*)/g))
1826
- .map(function (_a) {
1827
- var _b = __read(_a, 1), match = _b[0];
1828
- return match;
1829
- })
1830
- .filter(function (arg) { return arg !== ''; });
1831
- if (_.length > 1) {
1832
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1833
- _a = __read(_), command = _a[0], args = _a.slice(1);
1834
- }
1835
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1836
- if (options.args) {
1837
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1838
- args = __spreadArray(__spreadArray([], __read(args), false), __read(options.args), false);
1839
- }
1840
- var humanReadableCommand = !['npx', 'npm'].includes(command) ? command : args[0];
1841
- if (['ts-node'].includes(humanReadableCommand)) {
1842
- humanReadableCommand += " ".concat(args[1]);
1843
- }
1844
- return { command: command, humanReadableCommand: humanReadableCommand, args: args, cwd: cwd, crashOnError: crashOnError, timeout: timeout };
1845
- }
1846
- // TODO: This should show type error> execCommandNormalizeOptions({ command: '', commands: [''] });
1847
-
1848
- /**
1849
- * Run one command in a shell
1850
- *
1851
- * Note: There are 2 similar functions in the codebase:
1852
- * - `$execCommand` which runs a single command
1853
- * - `$execCommands` which runs multiple commands
1854
- *
1855
- * @public exported from `@promptbook/node`
1856
- */
1857
- function $execCommand(options) {
1858
- if (!$isRunningInNode()) {
1859
- throw new EnvironmentMismatchError('Function `$execCommand` can run only in Node environment.js');
1833
+ this.llmExecutionTools = llmExecutionTools;
1860
1834
  }
1861
- return new Promise(
1862
- // <- TODO: [🧱] Implement in a functional (not new Class) way
1863
- function (resolve, reject) {
1864
- // eslint-disable-next-line prefer-const
1865
- var _a = execCommandNormalizeOptions(options), command = _a.command, humanReadableCommand = _a.humanReadableCommand, args = _a.args, cwd = _a.cwd, crashOnError = _a.crashOnError, timeout = _a.timeout;
1866
- if (timeout !== Infinity) {
1867
- // TODO: In waitasecond forTime(Infinity) should be equivalent to forEver()
1868
- forTime(timeout).then(function () {
1869
- if (crashOnError) {
1870
- reject(new Error("Command \"".concat(humanReadableCommand, "\" exceeded time limit of ").concat(timeout, "ms")));
1871
- }
1872
- else {
1873
- console.warn("Command \"".concat(humanReadableCommand, "\" exceeded time limit of ").concat(timeout, "ms but continues running"));
1874
- resolve('Command exceeded time limit');
1875
- }
1876
- });
1877
- }
1878
- if (/^win/.test(process.platform) && ['npm', 'npx'].includes(command)) {
1879
- command = "".concat(command, ".cmd");
1880
- }
1881
- // !!!!!! Verbose mode - to all consoles
1882
- console.info(colors.yellow(cwd) + ' ' + colors.green(command) + ' ' + colors.blue(args.join(' ')));
1883
- try {
1884
- var commandProcess = spawn(command, args, { cwd: cwd, shell: true });
1885
- commandProcess.on('message', function (message) {
1886
- console.info({ message: message });
1887
- });
1888
- var output_1 = [];
1889
- commandProcess.stdout.on('data', function (stdout) {
1890
- output_1.push(stdout.toString());
1891
- console.info(stdout.toString());
1892
- });
1893
- commandProcess.stderr.on('data', function (stderr) {
1894
- output_1.push(stderr.toString());
1895
- if (stderr.toString().trim()) {
1896
- console.warn(stderr.toString());
1897
- }
1898
- });
1899
- var finishWithCode = function (code) {
1900
- if (code !== 0) {
1901
- if (crashOnError) {
1902
- reject(new Error(output_1.join('\n').trim() ||
1903
- "Command \"".concat(humanReadableCommand, "\" exited with code ").concat(code)));
1904
- }
1905
- else {
1906
- console.warn("Command \"".concat(humanReadableCommand, "\" exited with code ").concat(code));
1907
- resolve(spaceTrim$1(output_1.join('\n')));
1908
- }
1909
- }
1910
- else {
1911
- resolve(spaceTrim$1(output_1.join('\n')));
1835
+ Object.defineProperty(MultipleLlmExecutionTools.prototype, "title", {
1836
+ get: function () {
1837
+ return 'Multiple LLM Providers';
1838
+ },
1839
+ enumerable: false,
1840
+ configurable: true
1841
+ });
1842
+ Object.defineProperty(MultipleLlmExecutionTools.prototype, "description", {
1843
+ get: function () {
1844
+ return this.llmExecutionTools.map(function (_a, index) {
1845
+ var title = _a.title;
1846
+ return "".concat(index + 1, ") `").concat(title, "`");
1847
+ }).join('\n');
1848
+ },
1849
+ enumerable: false,
1850
+ configurable: true
1851
+ });
1852
+ /**
1853
+ * Check the configuration of all execution tools
1854
+ */
1855
+ MultipleLlmExecutionTools.prototype.checkConfiguration = function () {
1856
+ return __awaiter(this, void 0, void 0, function () {
1857
+ var _a, _b, llmExecutionTools, e_1_1;
1858
+ var e_1, _c;
1859
+ return __generator(this, function (_d) {
1860
+ switch (_d.label) {
1861
+ case 0:
1862
+ _d.trys.push([0, 5, 6, 7]);
1863
+ _a = __values(this.llmExecutionTools), _b = _a.next();
1864
+ _d.label = 1;
1865
+ case 1:
1866
+ if (!!_b.done) return [3 /*break*/, 4];
1867
+ llmExecutionTools = _b.value;
1868
+ return [4 /*yield*/, llmExecutionTools.checkConfiguration()];
1869
+ case 2:
1870
+ _d.sent();
1871
+ _d.label = 3;
1872
+ case 3:
1873
+ _b = _a.next();
1874
+ return [3 /*break*/, 1];
1875
+ case 4: return [3 /*break*/, 7];
1876
+ case 5:
1877
+ e_1_1 = _d.sent();
1878
+ e_1 = { error: e_1_1 };
1879
+ return [3 /*break*/, 7];
1880
+ case 6:
1881
+ try {
1882
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
1883
+ }
1884
+ finally { if (e_1) throw e_1.error; }
1885
+ return [7 /*endfinally*/];
1886
+ case 7: return [2 /*return*/];
1912
1887
  }
1913
- };
1914
- commandProcess.on('close', finishWithCode);
1915
- commandProcess.on('exit', finishWithCode);
1916
- commandProcess.on('disconnect', function () {
1917
- // Note: Unexpected disconnection should always result in rejection
1918
- reject(new Error("Command \"".concat(humanReadableCommand, "\" disconnected")));
1919
1888
  });
1920
- commandProcess.on('error', function (error) {
1921
- if (crashOnError) {
1922
- reject(new Error("Command \"".concat(humanReadableCommand, "\" failed: \n").concat(error.message)));
1923
- }
1924
- else {
1925
- console.warn(error);
1926
- resolve(spaceTrim$1(output_1.join('\n')));
1927
- }
1928
- });
1929
- }
1930
- catch (error) {
1931
- // Note: Unexpected error in sync code should always result in rejection
1932
- reject(error);
1933
- }
1934
- });
1935
- }
1936
- /**
1937
- * Note: [🟢 <- TODO: [🦖] !!!!!! Split scrapers into packages and enable] Code in this file should never be published outside of `@promptbook/node` and `@promptbook/cli`
1938
- */
1939
-
1940
- /**
1941
- * Checks if the file exists
1942
- *
1943
- * Note: `$` is used to indicate that this function is not a pure function - it looks at the filesystem
1944
- *
1945
- * @private within the repository
1946
- */
1947
- function $isFileExisting(filename) {
1948
- return __awaiter(this, void 0, void 0, function () {
1949
- var isReadAccessAllowed, isFile;
1950
- return __generator(this, function (_a) {
1951
- switch (_a.label) {
1952
- case 0:
1953
- if (!$isRunningInNode()) {
1954
- throw new EnvironmentMismatchError('Function `$isFileExisting` works only in Node environment.js');
1955
- }
1956
- return [4 /*yield*/, access(filename, constants.R_OK)
1957
- .then(function () { return true; })
1958
- .catch(function () { return false; })];
1959
- case 1:
1960
- isReadAccessAllowed = _a.sent();
1961
- if (!isReadAccessAllowed) {
1962
- return [2 /*return*/, false];
1963
- }
1964
- return [4 /*yield*/, stat(filename)
1965
- .then(function (fileStat) { return fileStat.isFile(); })
1966
- .catch(function () { return false; })];
1967
- case 2:
1968
- isFile = _a.sent();
1969
- return [2 /*return*/, isFile];
1970
- }
1971
- });
1972
- });
1973
- }
1974
- /**
1975
- * Note: [🟢 <- TODO: [🦖] !!!!!! Split scrapers into packages and enable] Code in this file should never be published outside of `@promptbook/node` and `@promptbook/cli`
1976
- * TODO: [🐠] This can be a validator - with variants that return true/false and variants that throw errors with meaningless messages
1977
- * TODO: [🖇] What about symlinks?
1978
- */
1979
-
1980
- /**
1981
- * Get the file extension from a file name
1982
- *
1983
- * @private within the repository
1984
- */
1985
- function getFileExtension(value) {
1986
- var match = value.match(/\.([0-9a-z]+)(?:[?#]|$)/i);
1987
- return match ? match[1].toLowerCase() : null;
1988
- }
1989
-
1990
- var defaultDiacriticsRemovalMap = [
1991
- {
1992
- base: 'A',
1993
- letters: '\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F',
1994
- },
1995
- { base: 'AA', letters: '\uA732' },
1996
- { base: 'AE', letters: '\u00C6\u01FC\u01E2' },
1997
- { base: 'AO', letters: '\uA734' },
1998
- { base: 'AU', letters: '\uA736' },
1999
- { base: 'AV', letters: '\uA738\uA73A' },
2000
- { base: 'AY', letters: '\uA73C' },
2001
- {
2002
- base: 'B',
2003
- letters: '\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181',
2004
- },
2005
- {
2006
- base: 'C',
2007
- letters: '\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E',
2008
- },
2009
- {
2010
- base: 'D',
2011
- letters: '\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779\u00D0',
2012
- },
2013
- { base: 'DZ', letters: '\u01F1\u01C4' },
2014
- { base: 'Dz', letters: '\u01F2\u01C5' },
2015
- {
2016
- base: 'E',
2017
- letters: '\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E',
2018
- },
2019
- { base: 'F', letters: '\u0046\u24BB\uFF26\u1E1E\u0191\uA77B' },
2020
- {
2021
- base: 'G',
2022
- letters: '\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E',
2023
- },
2024
- {
2025
- base: 'H',
2026
- letters: '\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D',
2027
- },
2028
- {
2029
- base: 'I',
2030
- letters: '\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197',
2031
- },
2032
- { base: 'J', letters: '\u004A\u24BF\uFF2A\u0134\u0248' },
2033
- {
2034
- base: 'K',
2035
- letters: '\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2',
2036
- },
2037
- {
2038
- base: 'L',
2039
- letters: '\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780',
2040
- },
2041
- { base: 'LJ', letters: '\u01C7' },
2042
- { base: 'Lj', letters: '\u01C8' },
2043
- { base: 'M', letters: '\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C' },
2044
- {
2045
- base: 'N',
2046
- letters: '\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4',
2047
- },
2048
- { base: 'NJ', letters: '\u01CA' },
2049
- { base: 'Nj', letters: '\u01CB' },
2050
- {
2051
- base: 'O',
2052
- letters: '\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C',
2053
- },
2054
- { base: 'OI', letters: '\u01A2' },
2055
- { base: 'OO', letters: '\uA74E' },
2056
- { base: 'OU', letters: '\u0222' },
2057
- { base: 'OE', letters: '\u008C\u0152' },
2058
- { base: 'oe', letters: '\u009C\u0153' },
2059
- {
2060
- base: 'P',
2061
- letters: '\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754',
2062
- },
2063
- { base: 'Q', letters: '\u0051\u24C6\uFF31\uA756\uA758\u024A' },
2064
- {
2065
- base: 'R',
2066
- letters: '\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782',
2067
- },
2068
- {
2069
- base: 'S',
2070
- letters: '\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784',
2071
- },
2072
- {
2073
- base: 'T',
2074
- letters: '\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786',
2075
- },
2076
- { base: 'TZ', letters: '\uA728' },
2077
- {
2078
- base: 'U',
2079
- letters: '\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244',
2080
- },
2081
- { base: 'V', letters: '\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245' },
2082
- { base: 'VY', letters: '\uA760' },
2083
- {
2084
- base: 'W',
2085
- letters: '\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72',
2086
- },
2087
- { base: 'X', letters: '\u0058\u24CD\uFF38\u1E8A\u1E8C' },
2088
- {
2089
- base: 'Y',
2090
- letters: '\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE',
2091
- },
2092
- {
2093
- base: 'Z',
2094
- letters: '\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762',
2095
- },
2096
- {
2097
- base: 'a',
2098
- letters: '\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250',
2099
- },
2100
- { base: 'aa', letters: '\uA733' },
2101
- { base: 'ae', letters: '\u00E6\u01FD\u01E3' },
2102
- { base: 'ao', letters: '\uA735' },
2103
- { base: 'au', letters: '\uA737' },
2104
- { base: 'av', letters: '\uA739\uA73B' },
2105
- { base: 'ay', letters: '\uA73D' },
2106
- {
2107
- base: 'b',
2108
- letters: '\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253',
2109
- },
2110
- {
2111
- base: 'c',
2112
- letters: '\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184',
2113
- },
2114
- {
2115
- base: 'd',
2116
- letters: '\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A',
2117
- },
2118
- { base: 'dz', letters: '\u01F3\u01C6' },
2119
- {
2120
- base: 'e',
2121
- letters: '\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD',
2122
- },
2123
- { base: 'f', letters: '\u0066\u24D5\uFF46\u1E1F\u0192\uA77C' },
2124
- {
2125
- base: 'g',
2126
- letters: '\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F',
2127
- },
2128
- {
2129
- base: 'h',
2130
- letters: '\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265',
2131
- },
2132
- { base: 'hv', letters: '\u0195' },
2133
- {
2134
- base: 'i',
2135
- letters: '\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131',
2136
- },
2137
- { base: 'j', letters: '\u006A\u24D9\uFF4A\u0135\u01F0\u0249' },
2138
- {
2139
- base: 'k',
2140
- letters: '\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3',
2141
- },
2142
- {
2143
- base: 'l',
2144
- letters: '\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747',
2145
- },
2146
- { base: 'lj', letters: '\u01C9' },
2147
- { base: 'm', letters: '\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F' },
2148
- {
2149
- base: 'n',
2150
- letters: '\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5',
2151
- },
2152
- { base: 'nj', letters: '\u01CC' },
2153
- {
2154
- base: 'o',
2155
- letters: '\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275',
2156
- },
2157
- { base: 'oi', letters: '\u01A3' },
2158
- { base: 'ou', letters: '\u0223' },
2159
- { base: 'oo', letters: '\uA74F' },
2160
- {
2161
- base: 'p',
2162
- letters: '\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755',
2163
- },
2164
- { base: 'q', letters: '\u0071\u24E0\uFF51\u024B\uA757\uA759' },
2165
- {
2166
- base: 'r',
2167
- letters: '\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783',
2168
- },
2169
- {
2170
- base: 's',
2171
- letters: '\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B',
2172
- },
2173
- {
2174
- base: 't',
2175
- letters: '\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787',
2176
- },
2177
- { base: 'tz', letters: '\uA729' },
2178
- {
2179
- base: 'u',
2180
- letters: '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289',
2181
- },
2182
- { base: 'v', letters: '\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C' },
2183
- { base: 'vy', letters: '\uA761' },
2184
- {
2185
- base: 'w',
2186
- letters: '\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73',
2187
- },
2188
- { base: 'x', letters: '\u0078\u24E7\uFF58\u1E8B\u1E8D' },
2189
- {
2190
- base: 'y',
2191
- letters: '\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF',
2192
- },
2193
- {
2194
- base: 'z',
2195
- letters: '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763',
2196
- },
2197
- ];
2198
- /**
2199
- * Map of letters from diacritic variant to diacritless variant
2200
- * Contains lowercase and uppercase separatelly
2201
- *
2202
- * > "á" => "a"
2203
- * > "ě" => "e"
2204
- * > "Ă" => "A"
2205
- * > ...
2206
- *
2207
- * @public exported from `@promptbook/utils`
2208
- */
2209
- var DIACRITIC_VARIANTS_LETTERS = {};
2210
- // tslint:disable-next-line: prefer-for-of
2211
- for (var i = 0; i < defaultDiacriticsRemovalMap.length; i++) {
2212
- var letters = defaultDiacriticsRemovalMap[i].letters;
2213
- // tslint:disable-next-line: prefer-for-of
2214
- for (var j = 0; j < letters.length; j++) {
2215
- DIACRITIC_VARIANTS_LETTERS[letters[j]] = defaultDiacriticsRemovalMap[i].base;
2216
- }
2217
- }
2218
- // <- TODO: [🍓] Put to maker function to save execution time if not needed
2219
- /*
2220
- @see https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript
2221
- Licensed under the Apache License, Version 2.0 (the "License");
2222
- you may not use this file except in compliance with the License.
2223
- You may obtain a copy of the License at
2224
-
2225
- http://www.apache.org/licenses/LICENSE-2.0
2226
-
2227
- Unless required by applicable law or agreed to in writing, software
2228
- distributed under the License is distributed on an "AS IS" BASIS,
2229
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2230
- See the License for the specific language governing permissions and
2231
- limitations under the License.
2232
- */
2233
-
2234
- /**
2235
- * @@@
2236
- *
2237
- * @param input @@@
2238
- * @returns @@@
2239
- * @public exported from `@promptbook/utils`
2240
- */
2241
- function removeDiacritics(input) {
2242
- /*eslint no-control-regex: "off"*/
2243
- return input.replace(/[^\u0000-\u007E]/g, function (a) {
2244
- return DIACRITIC_VARIANTS_LETTERS[a] || a;
2245
- });
2246
- }
2247
- /**
2248
- * TODO: [Ж] Variant for cyrillic (and in general non-latin) letters
2249
- */
2250
-
2251
- /**
2252
- * @@@
2253
- *
2254
- * @param text @@@
2255
- * @returns @@@
2256
- * @example 'hello-world'
2257
- * @example 'i-love-promptbook'
2258
- * @public exported from `@promptbook/utils`
2259
- */
2260
- function normalizeToKebabCase(text) {
2261
- var e_1, _a;
2262
- text = removeDiacritics(text);
2263
- var charType;
2264
- var lastCharType = 'OTHER';
2265
- var normalizedName = '';
2266
- try {
2267
- for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
2268
- var char = text_1_1.value;
2269
- var normalizedChar = void 0;
2270
- if (/^[a-z]$/.test(char)) {
2271
- charType = 'LOWERCASE';
2272
- normalizedChar = char;
2273
- }
2274
- else if (/^[A-Z]$/.test(char)) {
2275
- charType = 'UPPERCASE';
2276
- normalizedChar = char.toLowerCase();
2277
- }
2278
- else if (/^[0-9]$/.test(char)) {
2279
- charType = 'NUMBER';
2280
- normalizedChar = char;
2281
- }
2282
- else {
2283
- charType = 'OTHER';
2284
- normalizedChar = '-';
2285
- }
2286
- if (charType !== lastCharType &&
2287
- !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
2288
- !(lastCharType === 'NUMBER') &&
2289
- !(charType === 'NUMBER')) {
2290
- normalizedName += '-';
2291
- }
2292
- normalizedName += normalizedChar;
2293
- lastCharType = charType;
2294
- }
2295
- }
2296
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
2297
- finally {
2298
- try {
2299
- if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
2300
- }
2301
- finally { if (e_1) throw e_1.error; }
2302
- }
2303
- normalizedName = normalizedName.split(/-+/g).join('-');
2304
- normalizedName = normalizedName.split(/-?\/-?/g).join('/');
2305
- normalizedName = normalizedName.replace(/^-/, '');
2306
- normalizedName = normalizedName.replace(/-$/, '');
2307
- return normalizedName;
2308
- }
2309
-
2310
- /**
2311
- * Removes emojis from a string and fix whitespaces
2312
- *
2313
- * @param text with emojis
2314
- * @returns text without emojis
2315
- * @public exported from `@promptbook/utils`
2316
- */
2317
- function removeEmojis(text) {
2318
- // Replace emojis (and also ZWJ sequence) with hyphens
2319
- text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
2320
- text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
2321
- text = text.replace(/(\p{Extended_Pictographic})(\u{200D}\p{Extended_Pictographic})*/gu, '$1');
2322
- text = text.replace(/\p{Extended_Pictographic}/gu, '');
2323
- return text;
2324
- }
2325
-
2326
- /**
2327
- * Tests if given string is valid URL.
2328
- *
2329
- * Note: This does not check if the file exists only if the path is valid
2330
- * @public exported from `@promptbook/utils`
2331
- */
2332
- function isValidFilePath(filename) {
2333
- if (typeof filename !== 'string') {
2334
- return false;
2335
- }
2336
- var filenameSlashes = filename.split('\\').join('/');
2337
- // Absolute Unix path: /hello.txt
2338
- if (/^(\/)/i.test(filenameSlashes)) {
2339
- return true;
2340
- }
2341
- // Absolute Windows path: /hello.txt
2342
- if (/^([A-Z]{1,2}:\/?)\//i.test(filenameSlashes)) {
2343
- return true;
2344
- }
2345
- // Relative path: ./hello.txt
2346
- if (/^(\.\.?\/)+/i.test(filenameSlashes)) {
2347
- return true;
2348
- }
2349
- return false;
2350
- }
2351
-
2352
- /**
2353
- * @@@
2354
- *
2355
- * @param value @@@
2356
- * @returns @@@
2357
- * @example @@@
2358
- * @public exported from `@promptbook/utils`
2359
- */
2360
- function titleToName(value) {
2361
- if (isValidUrl(value)) {
2362
- value = value.replace(/^https?:\/\//, '');
2363
- value = value.replace(/\.html$/, '');
2364
- }
2365
- else if (isValidFilePath(value)) {
2366
- value = basename(value);
2367
- // Note: Keeping extension in the name
2368
- }
2369
- value = value.split('/').join('-');
2370
- value = removeEmojis(value);
2371
- value = normalizeToKebabCase(value);
2372
- // TODO: [🧠] Maybe warn or add some padding to short name which are not good identifiers
2373
- return value;
2374
- }
2375
-
2376
- /**
2377
- * @@@
2378
- *
2379
- * @private for `FileCacheStorage`
2380
- */
2381
- function nameToSubfolderPath(name) {
2382
- return [name.substr(0, 1).toLowerCase(), name.substr(1, 1).toLowerCase()];
2383
- }
2384
-
2385
- /**
2386
- * Just marks a place of place where should be something implemented
2387
- * No side effects.
2388
- *
2389
- * Note: It can be usefull suppressing eslint errors of unused variables
2390
- *
2391
- * @param value any values
2392
- * @returns void
2393
- * @private within the repository
2394
- */
2395
- function TODO_USE() {
2396
- var value = [];
2397
- for (var _i = 0; _i < arguments.length; _i++) {
2398
- value[_i] = arguments[_i];
2399
- }
2400
- }
2401
-
2402
- /**
2403
- * Create a filename for intermediate cache for scrapers
2404
- *
2405
- * Note: It also checks if directory exists and creates it if not
2406
- *
2407
- * @private as internal utility for scrapers
2408
- */
2409
- function getScraperIntermediateSource(source, options) {
2410
- return __awaiter(this, void 0, void 0, function () {
2411
- var sourceFilename, url, rootDirname, cacheDirname, isCacheCleaned, extension, isVerbose, hash, semanticName, pieces, name, cacheFilename, isDestroyed, fileHandler;
2412
- return __generator(this, function (_a) {
2413
- switch (_a.label) {
2414
- case 0:
2415
- sourceFilename = source.filename, url = source.url;
2416
- rootDirname = options.rootDirname, cacheDirname = options.cacheDirname, isCacheCleaned = options.isCacheCleaned, extension = options.extension, isVerbose = options.isVerbose;
2417
- hash = SHA256(
2418
- // <- TODO: [🥬] Encapsulate sha256 to some private utility function
2419
- hexEncoder.parse(sourceFilename || url || 'untitled'))
2420
- .toString( /* hex */)
2421
- .substring(0, 20);
2422
- semanticName = normalizeToKebabCase(titleToName((sourceFilename || url || '').split('intermediate').join(''))).substring(0, 20);
2423
- pieces = ['intermediate', semanticName, hash].filter(function (piece) { return piece !== ''; });
2424
- name = pieces.join('-').split('--').join('-');
2425
- // <- TODO: Use MAX_FILENAME_LENGTH
2426
- TODO_USE(rootDirname); // <- TODO: !!!!!!
2427
- cacheFilename = join.apply(void 0, __spreadArray(__spreadArray([process.cwd(),
2428
- cacheDirname], __read(nameToSubfolderPath(hash /* <- TODO: [🎎] Maybe add some SHA256 prefix */)), false), [name], false)).split('\\')
2429
- .join('/') +
2430
- '.' +
2431
- extension;
2432
- return [4 /*yield*/, mkdir(dirname(cacheFilename), { recursive: true })];
2433
- case 1:
2434
- _a.sent();
2435
- isDestroyed = true;
2436
- fileHandler = {
2437
- filename: cacheFilename,
2438
- get isDestroyed() {
2439
- return isDestroyed;
2440
- },
2441
- destroy: function () {
2442
- return __awaiter(this, void 0, void 0, function () {
2443
- return __generator(this, function (_a) {
2444
- switch (_a.label) {
2445
- case 0:
2446
- if (!isCacheCleaned) return [3 /*break*/, 2];
2447
- if (isVerbose) {
2448
- console.info('legacyDocumentScraper: Clening cache');
2449
- }
2450
- return [4 /*yield*/, rm(cacheFilename)];
2451
- case 1:
2452
- _a.sent();
2453
- _a.label = 2;
2454
- case 2:
2455
- isDestroyed = true;
2456
- return [2 /*return*/];
2457
- }
2458
- });
2459
- });
2460
- },
2461
- };
2462
- return [2 /*return*/, fileHandler];
2463
- }
2464
- });
2465
- });
2466
- }
2467
- /**
2468
- * Note: Not using `FileCacheStorage` for two reasons:
2469
- * 1) Need to store more than serialized JSONs
2470
- * 2) Need to switch between a `rootDirname` and `cacheDirname` <- TODO: !!!!
2471
- * TODO: [🐱‍🐉][🧠] Make some smart crop
2472
- */
2473
-
2474
- var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",resultingParameterName:"knowledgePieces",dependentParameterNames:["knowledgeContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",resultingParameterName:"keywords",dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Sample\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n- Your output format is JSON object\n- Write just the JSON object, no other text should be present\n- It contains the following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",resultingParameterName:"modelRequirements",format:"JSON",dependentParameterNames:["availableModelNames","personaDescription"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
2475
-
2476
- /**
2477
- * This error indicates errors during the execution of the pipeline
2478
- *
2479
- * @public exported from `@promptbook/core`
2480
- */
2481
- var PipelineExecutionError = /** @class */ (function (_super) {
2482
- __extends(PipelineExecutionError, _super);
2483
- function PipelineExecutionError(message) {
2484
- var _this = _super.call(this, message) || this;
2485
- _this.name = 'PipelineExecutionError';
2486
- Object.setPrototypeOf(_this, PipelineExecutionError.prototype);
2487
- return _this;
2488
- }
2489
- return PipelineExecutionError;
2490
- }(Error));
2491
-
2492
- /**
2493
- * This error indicates that the pipeline collection cannot be propperly loaded
2494
- *
2495
- * @public exported from `@promptbook/core`
2496
- */
2497
- var CollectionError = /** @class */ (function (_super) {
2498
- __extends(CollectionError, _super);
2499
- function CollectionError(message) {
2500
- var _this = _super.call(this, message) || this;
2501
- _this.name = 'CollectionError';
2502
- Object.setPrototypeOf(_this, CollectionError.prototype);
2503
- return _this;
2504
- }
2505
- return CollectionError;
2506
- }(Error));
2507
-
2508
- /**
2509
- * This error occurs when some expectation is not met in the execution of the pipeline
2510
- *
2511
- * @public exported from `@promptbook/core`
2512
- * Note: Do not throw this error, its reserved for `checkExpectations` and `createPipelineExecutor` and public ONLY to be serializable through remote server
2513
- * Note: Always thrown in `checkExpectations` and catched in `createPipelineExecutor` and rethrown as `PipelineExecutionError`
2514
- * Note: This is a kindof subtype of PipelineExecutionError
2515
- */
2516
- var ExpectError = /** @class */ (function (_super) {
2517
- __extends(ExpectError, _super);
2518
- function ExpectError(message) {
2519
- var _this = _super.call(this, message) || this;
2520
- _this.name = 'ExpectError';
2521
- Object.setPrototypeOf(_this, ExpectError.prototype);
2522
- return _this;
2523
- }
2524
- return ExpectError;
2525
- }(Error));
2526
-
2527
- /**
2528
- * This error type indicates that some limit was reached
2529
- *
2530
- * @public exported from `@promptbook/core`
2531
- */
2532
- var LimitReachedError = /** @class */ (function (_super) {
2533
- __extends(LimitReachedError, _super);
2534
- function LimitReachedError(message) {
2535
- var _this = _super.call(this, message) || this;
2536
- _this.name = 'LimitReachedError';
2537
- Object.setPrototypeOf(_this, LimitReachedError.prototype);
2538
- return _this;
2539
- }
2540
- return LimitReachedError;
2541
- }(Error));
2542
-
2543
- /**
2544
- * This error type indicates that some part of the code is not implemented yet
2545
- *
2546
- * @public exported from `@promptbook/core`
2547
- */
2548
- var NotYetImplementedError = /** @class */ (function (_super) {
2549
- __extends(NotYetImplementedError, _super);
2550
- function NotYetImplementedError(message) {
2551
- var _this = _super.call(this, spaceTrim$1(function (block) { return "\n ".concat(block(message), "\n\n Note: This feature is not implemented yet but it will be soon.\n\n If you want speed up the implementation or just read more, look here:\n https://github.com/webgptorg/promptbook\n\n Or contact us on me@pavolhejny.com\n\n "); })) || this;
2552
- _this.name = 'NotYetImplementedError';
2553
- Object.setPrototypeOf(_this, NotYetImplementedError.prototype);
2554
- return _this;
2555
- }
2556
- return NotYetImplementedError;
2557
- }(Error));
2558
-
2559
- /**
2560
- * Index of all custom errors
2561
- *
2562
- * @public exported from `@promptbook/core`
2563
- */
2564
- var ERRORS = {
2565
- ExpectError: ExpectError,
2566
- CollectionError: CollectionError,
2567
- EnvironmentMismatchError: EnvironmentMismatchError,
2568
- LimitReachedError: LimitReachedError,
2569
- NotFoundError: NotFoundError,
2570
- NotYetImplementedError: NotYetImplementedError,
2571
- ParseError: ParseError,
2572
- PipelineExecutionError: PipelineExecutionError,
2573
- PipelineLogicError: PipelineLogicError,
2574
- PipelineUrlError: PipelineUrlError,
2575
- UnexpectedError: UnexpectedError,
2576
- // TODO: [🪑]> VersionMismatchError,
2577
- };
2578
-
2579
- /**
2580
- * Deserializes the error object
2581
- *
2582
- * @public exported from `@promptbook/utils`
2583
- */
2584
- function deserializeError(error) {
2585
- if (error.name === 'Error') {
2586
- return new Error(error.message);
2587
- }
2588
- var CustomError = ERRORS[error.name];
2589
- return new CustomError(error.message);
2590
- }
2591
-
2592
- /**
2593
- * Asserts that the execution of a Promptbook is successful
2594
- *
2595
- * @param executionResult - The partial result of the Promptbook execution
2596
- * @throws {PipelineExecutionError} If the execution is not successful or if multiple errors occurred
2597
- * @public exported from `@promptbook/core`
2598
- */
2599
- function assertsExecutionSuccessful(executionResult) {
2600
- var isSuccessful = executionResult.isSuccessful, errors = executionResult.errors;
2601
- if (isSuccessful === true) {
2602
- return;
2603
- }
2604
- if (errors.length === 0) {
2605
- throw new PipelineExecutionError("Promptbook Execution failed because of unknown reason");
2606
- }
2607
- else if (errors.length === 1) {
2608
- throw deserializeError(errors[0]);
2609
- }
2610
- else {
2611
- throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Multiple errors occurred during Promptbook execution\n\n ".concat(block(errors
2612
- .map(function (_a, index) {
2613
- var name = _a.name, stack = _a.stack, message = _a.message;
2614
- return spaceTrim$1(function (block) { return "\n ".concat(name, " ").concat(index + 1, ":\n ").concat(block(stack || message), "\n "); });
2615
- })
2616
- .join('\n')), "\n "); }));
2617
- }
2618
- }
2619
- /**
2620
- * TODO: [🧠] Can this return type be better typed than void
2621
- */
2622
-
2623
- /**
2624
- * Determine if the pipeline is fully prepared
2625
- *
2626
- * @public exported from `@promptbook/core`
2627
- */
2628
- function isPipelinePrepared(pipeline) {
2629
- // Note: Ignoring `pipeline.preparations` @@@
2630
- // Note: Ignoring `pipeline.knowledgePieces` @@@
2631
- if (!pipeline.personas.every(function (persona) { return persona.modelRequirements !== undefined; })) {
2632
- return false;
2633
- }
2634
- if (!pipeline.knowledgeSources.every(function (knowledgeSource) { return knowledgeSource.preparationIds !== undefined; })) {
2635
- return false;
2636
- }
2637
- /*
2638
- TODO: [🧠][🍫] `templates` can not be determined if they are fully prepared SO ignoring them
2639
- > if (!pipeline.templates.every(({ preparedContent }) => preparedContent === undefined)) {
2640
- > return false;
2641
- > }
2642
- */
2643
- return true;
2644
- }
2645
- /**
2646
- * TODO: [🔃][main] !!!!! If the pipeline was prepared with different version or different set of models, prepare it once again
2647
- * TODO: [🐠] Maybe base this on `makeValidator`
2648
- * TODO: [🧊] Pipeline can be partially prepared, this should return true ONLY if fully prepared
2649
- * TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
2650
- * - [🏍] ? Is context in each template
2651
- * - [♨] Are samples prepared
2652
- * - [♨] Are templates prepared
2653
- */
2654
-
2655
- /**
2656
- * Serializes an error into a [🚉] JSON-serializable object
2657
- *
2658
- * @public exported from `@promptbook/utils`
2659
- */
2660
- function serializeError(error) {
2661
- var name = error.name, message = error.message, stack = error.stack;
2662
- if (!__spreadArray(['Error'], __read(Object.keys(ERRORS)), false).includes(name)) {
2663
- throw new UnexpectedError(spaceTrim(function (block) { return "\n \n Cannot serialize error with name \"".concat(name, "\"\n\n ").concat(block(stack || message), "\n \n "); }));
2664
- }
2665
- return {
2666
- name: name,
2667
- message: message,
2668
- stack: stack,
2669
- };
2670
- }
2671
-
2672
- /**
2673
- * Multiple LLM Execution Tools is a proxy server that uses multiple execution tools internally and exposes the executor interface externally.
2674
- *
2675
- * Note: Internal utility of `joinLlmExecutionTools` but exposed type
2676
- * @public exported from `@promptbook/types`
2677
- */
2678
- var MultipleLlmExecutionTools = /** @class */ (function () {
2679
- /**
2680
- * Gets array of execution tools in order of priority
2681
- */
2682
- function MultipleLlmExecutionTools() {
2683
- var llmExecutionTools = [];
2684
- for (var _i = 0; _i < arguments.length; _i++) {
2685
- llmExecutionTools[_i] = arguments[_i];
2686
- }
2687
- this.llmExecutionTools = llmExecutionTools;
2688
- }
2689
- Object.defineProperty(MultipleLlmExecutionTools.prototype, "title", {
2690
- get: function () {
2691
- return 'Multiple LLM Providers';
2692
- },
2693
- enumerable: false,
2694
- configurable: true
2695
- });
2696
- Object.defineProperty(MultipleLlmExecutionTools.prototype, "description", {
2697
- get: function () {
2698
- return this.llmExecutionTools.map(function (_a, index) {
2699
- var title = _a.title;
2700
- return "".concat(index + 1, ") `").concat(title, "`");
2701
- }).join('\n');
2702
- },
2703
- enumerable: false,
2704
- configurable: true
2705
- });
2706
- /**
2707
- * Check the configuration of all execution tools
2708
- */
2709
- MultipleLlmExecutionTools.prototype.checkConfiguration = function () {
2710
- return __awaiter(this, void 0, void 0, function () {
2711
- var _a, _b, llmExecutionTools, e_1_1;
2712
- var e_1, _c;
2713
- return __generator(this, function (_d) {
2714
- switch (_d.label) {
2715
- case 0:
2716
- _d.trys.push([0, 5, 6, 7]);
2717
- _a = __values(this.llmExecutionTools), _b = _a.next();
2718
- _d.label = 1;
2719
- case 1:
2720
- if (!!_b.done) return [3 /*break*/, 4];
2721
- llmExecutionTools = _b.value;
2722
- return [4 /*yield*/, llmExecutionTools.checkConfiguration()];
2723
- case 2:
2724
- _d.sent();
2725
- _d.label = 3;
2726
- case 3:
2727
- _b = _a.next();
2728
- return [3 /*break*/, 1];
2729
- case 4: return [3 /*break*/, 7];
2730
- case 5:
2731
- e_1_1 = _d.sent();
2732
- e_1 = { error: e_1_1 };
2733
- return [3 /*break*/, 7];
2734
- case 6:
2735
- try {
2736
- if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
2737
- }
2738
- finally { if (e_1) throw e_1.error; }
2739
- return [7 /*endfinally*/];
2740
- case 7: return [2 /*return*/];
2741
- }
2742
- });
2743
- });
2744
- };
2745
- /**
2746
- * List all available models that can be used
2747
- * This lists is a combination of all available models from all execution tools
2748
- */
2749
- MultipleLlmExecutionTools.prototype.listModels = function () {
2750
- return __awaiter(this, void 0, void 0, function () {
2751
- var availableModels, _a, _b, llmExecutionTools, models, e_2_1;
2752
- var e_2, _c;
2753
- return __generator(this, function (_d) {
2754
- switch (_d.label) {
2755
- case 0:
2756
- availableModels = [];
2757
- _d.label = 1;
2758
- case 1:
2759
- _d.trys.push([1, 6, 7, 8]);
2760
- _a = __values(this.llmExecutionTools), _b = _a.next();
2761
- _d.label = 2;
2762
- case 2:
2763
- if (!!_b.done) return [3 /*break*/, 5];
2764
- llmExecutionTools = _b.value;
2765
- return [4 /*yield*/, llmExecutionTools.listModels()];
2766
- case 3:
2767
- models = _d.sent();
2768
- availableModels.push.apply(availableModels, __spreadArray([], __read(models), false));
2769
- _d.label = 4;
2770
- case 4:
2771
- _b = _a.next();
2772
- return [3 /*break*/, 2];
2773
- case 5: return [3 /*break*/, 8];
2774
- case 6:
2775
- e_2_1 = _d.sent();
2776
- e_2 = { error: e_2_1 };
2777
- return [3 /*break*/, 8];
2778
- case 7:
2779
- try {
2780
- if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
2781
- }
2782
- finally { if (e_2) throw e_2.error; }
2783
- return [7 /*endfinally*/];
2784
- case 8: return [2 /*return*/, availableModels];
1889
+ });
1890
+ };
1891
+ /**
1892
+ * List all available models that can be used
1893
+ * This lists is a combination of all available models from all execution tools
1894
+ */
1895
+ MultipleLlmExecutionTools.prototype.listModels = function () {
1896
+ return __awaiter(this, void 0, void 0, function () {
1897
+ var availableModels, _a, _b, llmExecutionTools, models, e_2_1;
1898
+ var e_2, _c;
1899
+ return __generator(this, function (_d) {
1900
+ switch (_d.label) {
1901
+ case 0:
1902
+ availableModels = [];
1903
+ _d.label = 1;
1904
+ case 1:
1905
+ _d.trys.push([1, 6, 7, 8]);
1906
+ _a = __values(this.llmExecutionTools), _b = _a.next();
1907
+ _d.label = 2;
1908
+ case 2:
1909
+ if (!!_b.done) return [3 /*break*/, 5];
1910
+ llmExecutionTools = _b.value;
1911
+ return [4 /*yield*/, llmExecutionTools.listModels()];
1912
+ case 3:
1913
+ models = _d.sent();
1914
+ availableModels.push.apply(availableModels, __spreadArray([], __read(models), false));
1915
+ _d.label = 4;
1916
+ case 4:
1917
+ _b = _a.next();
1918
+ return [3 /*break*/, 2];
1919
+ case 5: return [3 /*break*/, 8];
1920
+ case 6:
1921
+ e_2_1 = _d.sent();
1922
+ e_2 = { error: e_2_1 };
1923
+ return [3 /*break*/, 8];
1924
+ case 7:
1925
+ try {
1926
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
1927
+ }
1928
+ finally { if (e_2) throw e_2.error; }
1929
+ return [7 /*endfinally*/];
1930
+ case 8: return [2 /*return*/, availableModels];
2785
1931
  }
2786
1932
  });
2787
1933
  });
@@ -2900,232 +2046,445 @@ var MultipleLlmExecutionTools = /** @class */ (function () {
2900
2046
  }
2901
2047
  }
2902
2048
  });
2903
- });
2904
- };
2905
- return MultipleLlmExecutionTools;
2906
- }());
2049
+ });
2050
+ };
2051
+ return MultipleLlmExecutionTools;
2052
+ }());
2053
+ /**
2054
+ * TODO: [🧠][🎛] Aggregating multiple models - have result not only from one first aviable model BUT all of them
2055
+ * TODO: [🏖] If no llmTools have for example not defined `callCompletionModel` this will still return object with defined `callCompletionModel` which just throws `PipelineExecutionError`, make it undefined instead
2056
+ * Look how `countTotalUsage` (and `cacheLlmTools`) implements it
2057
+ */
2058
+
2059
+ /**
2060
+ * Joins multiple LLM Execution Tools into one
2061
+ *
2062
+ * @returns {LlmExecutionTools} Single wrapper for multiple LlmExecutionTools
2063
+ *
2064
+ * 0) If there is no LlmExecutionTools, it warns and returns valid but empty LlmExecutionTools
2065
+ * 1) If there is only one LlmExecutionTools, it returns it wrapped in a proxy object
2066
+ * 2) If there are multiple LlmExecutionTools, first will be used first, second will be used if the first hasn`t defined model variant or fails, etc.
2067
+ * 3) When all LlmExecutionTools fail, it throws an error with a list of all errors merged into one
2068
+ *
2069
+ *
2070
+ * Tip: You don't have to use this function directly, just pass an array of LlmExecutionTools to the `ExecutionTools`
2071
+ *
2072
+ * @public exported from `@promptbook/core`
2073
+ */
2074
+ function joinLlmExecutionTools() {
2075
+ var llmExecutionTools = [];
2076
+ for (var _i = 0; _i < arguments.length; _i++) {
2077
+ llmExecutionTools[_i] = arguments[_i];
2078
+ }
2079
+ if (llmExecutionTools.length === 0) {
2080
+ var warningMessage = spaceTrim("\n You have not provided any `LlmExecutionTools`\n This means that you won't be able to execute any prompts that require large language models like GPT-4 or Anthropic's Claude.\n\n Technically, it's not an error, but it's probably not what you want because it does not make sense to use Promptbook without language models.\n ");
2081
+ // TODO: [🟥] Detect browser / node and make it colorfull
2082
+ console.warn(warningMessage);
2083
+ /*
2084
+ return {
2085
+ async listModels() {
2086
+ // TODO: [🟥] Detect browser / node and make it colorfull
2087
+ console.warn(
2088
+ spaceTrim(
2089
+ (block) => `
2090
+
2091
+ You can't list models because you have no LLM Execution Tools defined:
2092
+
2093
+ tl;dr
2094
+
2095
+ ${block(warningMessage)}
2096
+ `,
2097
+ ),
2098
+ );
2099
+ return [];
2100
+ },
2101
+ };
2102
+ */
2103
+ }
2104
+ return new (MultipleLlmExecutionTools.bind.apply(MultipleLlmExecutionTools, __spreadArray([void 0], __read(llmExecutionTools), false)))();
2105
+ }
2106
+ /**
2107
+ * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
2108
+ */
2109
+
2110
+ /**
2111
+ * @@@
2112
+ *
2113
+ * @public exported from `@promptbook/utils`
2114
+ */
2115
+ function deepClone(objectValue) {
2116
+ return JSON.parse(JSON.stringify(objectValue));
2117
+ /*
2118
+ TODO: [🧠] Is there a better implementation?
2119
+ > const propertyNames = Object.getOwnPropertyNames(objectValue);
2120
+ > for (const propertyName of propertyNames) {
2121
+ > const value = (objectValue as really_any)[propertyName];
2122
+ > if (value && typeof value === 'object') {
2123
+ > deepClone(value);
2124
+ > }
2125
+ > }
2126
+ > return Object.assign({}, objectValue);
2127
+ */
2128
+ }
2129
+ /**
2130
+ * TODO: [🧠] Is there a way how to meaningfully test this utility
2131
+ */
2132
+
2133
+ /**
2134
+ * Function `addUsage` will add multiple usages into one
2135
+ *
2136
+ * Note: If you provide 0 values, it returns ZERO_USAGE
2137
+ *
2138
+ * @public exported from `@promptbook/core`
2139
+ */
2140
+ function addUsage() {
2141
+ var usageItems = [];
2142
+ for (var _i = 0; _i < arguments.length; _i++) {
2143
+ usageItems[_i] = arguments[_i];
2144
+ }
2145
+ return usageItems.reduce(function (acc, item) {
2146
+ var e_1, _a, e_2, _b;
2147
+ var _c;
2148
+ acc.price.value += ((_c = item.price) === null || _c === void 0 ? void 0 : _c.value) || 0;
2149
+ try {
2150
+ for (var _d = __values(Object.keys(acc.input)), _e = _d.next(); !_e.done; _e = _d.next()) {
2151
+ var key = _e.value;
2152
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2153
+ //@ts-ignore
2154
+ if (item.input[key]) {
2155
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2156
+ //@ts-ignore
2157
+ acc.input[key].value += item.input[key].value || 0;
2158
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2159
+ //@ts-ignore
2160
+ if (item.input[key].isUncertain) {
2161
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2162
+ //@ts-ignore
2163
+ acc.input[key].isUncertain = true;
2164
+ }
2165
+ }
2166
+ }
2167
+ }
2168
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
2169
+ finally {
2170
+ try {
2171
+ if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
2172
+ }
2173
+ finally { if (e_1) throw e_1.error; }
2174
+ }
2175
+ try {
2176
+ for (var _f = __values(Object.keys(acc.output)), _g = _f.next(); !_g.done; _g = _f.next()) {
2177
+ var key = _g.value;
2178
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2179
+ //@ts-ignore
2180
+ if (item.output[key]) {
2181
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2182
+ //@ts-ignore
2183
+ acc.output[key].value += item.output[key].value || 0;
2184
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2185
+ //@ts-ignore
2186
+ if (item.output[key].isUncertain) {
2187
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2188
+ //@ts-ignore
2189
+ acc.output[key].isUncertain = true;
2190
+ }
2191
+ }
2192
+ }
2193
+ }
2194
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
2195
+ finally {
2196
+ try {
2197
+ if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
2198
+ }
2199
+ finally { if (e_2) throw e_2.error; }
2200
+ }
2201
+ return acc;
2202
+ }, deepClone(ZERO_USAGE));
2203
+ }
2204
+
2205
+ /**
2206
+ * Intercepts LLM tools and counts total usage of the tools
2207
+ *
2208
+ * @param llmTools LLM tools to be intercepted with usage counting
2209
+ * @returns LLM tools with same functionality with added total cost counting
2210
+ * @public exported from `@promptbook/core`
2211
+ */
2212
+ function countTotalUsage(llmTools) {
2213
+ var _this = this;
2214
+ var totalUsage = ZERO_USAGE;
2215
+ var proxyTools = {
2216
+ get title() {
2217
+ // TODO: [🧠] Maybe put here some suffix
2218
+ return llmTools.title;
2219
+ },
2220
+ get description() {
2221
+ // TODO: [🧠] Maybe put here some suffix
2222
+ return llmTools.description;
2223
+ },
2224
+ checkConfiguration: function () {
2225
+ return __awaiter(this, void 0, void 0, function () {
2226
+ return __generator(this, function (_a) {
2227
+ return [2 /*return*/, /* not await */ llmTools.checkConfiguration()];
2228
+ });
2229
+ });
2230
+ },
2231
+ listModels: function () {
2232
+ return /* not await */ llmTools.listModels();
2233
+ },
2234
+ getTotalUsage: function () {
2235
+ // <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
2236
+ return totalUsage;
2237
+ },
2238
+ };
2239
+ if (llmTools.callChatModel !== undefined) {
2240
+ proxyTools.callChatModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
2241
+ var promptResult;
2242
+ return __generator(this, function (_a) {
2243
+ switch (_a.label) {
2244
+ case 0: return [4 /*yield*/, llmTools.callChatModel(prompt)];
2245
+ case 1:
2246
+ promptResult = _a.sent();
2247
+ totalUsage = addUsage(totalUsage, promptResult.usage);
2248
+ return [2 /*return*/, promptResult];
2249
+ }
2250
+ });
2251
+ }); };
2252
+ }
2253
+ if (llmTools.callCompletionModel !== undefined) {
2254
+ proxyTools.callCompletionModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
2255
+ var promptResult;
2256
+ return __generator(this, function (_a) {
2257
+ switch (_a.label) {
2258
+ case 0: return [4 /*yield*/, llmTools.callCompletionModel(prompt)];
2259
+ case 1:
2260
+ promptResult = _a.sent();
2261
+ totalUsage = addUsage(totalUsage, promptResult.usage);
2262
+ return [2 /*return*/, promptResult];
2263
+ }
2264
+ });
2265
+ }); };
2266
+ }
2267
+ if (llmTools.callEmbeddingModel !== undefined) {
2268
+ proxyTools.callEmbeddingModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
2269
+ var promptResult;
2270
+ return __generator(this, function (_a) {
2271
+ switch (_a.label) {
2272
+ case 0: return [4 /*yield*/, llmTools.callEmbeddingModel(prompt)];
2273
+ case 1:
2274
+ promptResult = _a.sent();
2275
+ totalUsage = addUsage(totalUsage, promptResult.usage);
2276
+ return [2 /*return*/, promptResult];
2277
+ }
2278
+ });
2279
+ }); };
2280
+ }
2281
+ // <- Note: [🤖]
2282
+ return proxyTools;
2283
+ }
2907
2284
  /**
2908
- * TODO: [🧠][🎛] Aggregating multiple models - have result not only from one first aviable model BUT all of them
2909
- * TODO: [🏖] If no llmTools have for example not defined `callCompletionModel` this will still return object with defined `callCompletionModel` which just throws `PipelineExecutionError`, make it undefined instead
2910
- * Look how `countTotalUsage` (and `cacheLlmTools`) implements it
2285
+ * TODO: [🧠][💸] Maybe make some common abstraction `interceptLlmTools` and use here (or use javascript Proxy?)
2286
+ * TODO: [🧠] Is there some meaningfull way how to test this util
2287
+ * TODO: [🧠][🌯] Maybe a way how to hide ability to `get totalUsage`
2288
+ * > const [llmToolsWithUsage,getUsage] = countTotalUsage(llmTools);
2289
+ * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
2911
2290
  */
2912
2291
 
2292
+ var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",resultingParameterName:"knowledgePieces",dependentParameterNames:["knowledgeContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",resultingParameterName:"keywords",dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],templates:[{templateType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Sample\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n- Your output format is JSON object\n- Write just the JSON object, no other text should be present\n- It contains the following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",resultingParameterName:"modelRequirements",format:"JSON",dependentParameterNames:["availableModelNames","personaDescription"]}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
2293
+
2913
2294
  /**
2914
- * Joins multiple LLM Execution Tools into one
2915
- *
2916
- * @returns {LlmExecutionTools} Single wrapper for multiple LlmExecutionTools
2917
- *
2918
- * 0) If there is no LlmExecutionTools, it warns and returns valid but empty LlmExecutionTools
2919
- * 1) If there is only one LlmExecutionTools, it returns it wrapped in a proxy object
2920
- * 2) If there are multiple LlmExecutionTools, first will be used first, second will be used if the first hasn`t defined model variant or fails, etc.
2921
- * 3) When all LlmExecutionTools fail, it throws an error with a list of all errors merged into one
2922
- *
2923
- *
2924
- * Tip: You don't have to use this function directly, just pass an array of LlmExecutionTools to the `ExecutionTools`
2295
+ * This error indicates that the pipeline collection cannot be propperly loaded
2925
2296
  *
2926
2297
  * @public exported from `@promptbook/core`
2927
2298
  */
2928
- function joinLlmExecutionTools() {
2929
- var llmExecutionTools = [];
2930
- for (var _i = 0; _i < arguments.length; _i++) {
2931
- llmExecutionTools[_i] = arguments[_i];
2299
+ var CollectionError = /** @class */ (function (_super) {
2300
+ __extends(CollectionError, _super);
2301
+ function CollectionError(message) {
2302
+ var _this = _super.call(this, message) || this;
2303
+ _this.name = 'CollectionError';
2304
+ Object.setPrototypeOf(_this, CollectionError.prototype);
2305
+ return _this;
2932
2306
  }
2933
- if (llmExecutionTools.length === 0) {
2934
- var warningMessage = spaceTrim("\n You have not provided any `LlmExecutionTools`\n This means that you won't be able to execute any prompts that require large language models like GPT-4 or Anthropic's Claude.\n\n Technically, it's not an error, but it's probably not what you want because it does not make sense to use Promptbook without language models.\n ");
2935
- // TODO: [🟥] Detect browser / node and make it colorfull
2936
- console.warn(warningMessage);
2937
- /*
2938
- return {
2939
- async listModels() {
2940
- // TODO: [🟥] Detect browser / node and make it colorfull
2941
- console.warn(
2942
- spaceTrim(
2943
- (block) => `
2307
+ return CollectionError;
2308
+ }(Error));
2944
2309
 
2945
- You can't list models because you have no LLM Execution Tools defined:
2310
+ /**
2311
+ * This error type indicates that you try to use a feature that is not available in the current environment
2312
+ *
2313
+ * @public exported from `@promptbook/core`
2314
+ */
2315
+ var EnvironmentMismatchError = /** @class */ (function (_super) {
2316
+ __extends(EnvironmentMismatchError, _super);
2317
+ function EnvironmentMismatchError(message) {
2318
+ var _this = _super.call(this, message) || this;
2319
+ _this.name = 'EnvironmentMismatchError';
2320
+ Object.setPrototypeOf(_this, EnvironmentMismatchError.prototype);
2321
+ return _this;
2322
+ }
2323
+ return EnvironmentMismatchError;
2324
+ }(Error));
2946
2325
 
2947
- tl;dr
2326
+ /**
2327
+ * This error occurs when some expectation is not met in the execution of the pipeline
2328
+ *
2329
+ * @public exported from `@promptbook/core`
2330
+ * Note: Do not throw this error, its reserved for `checkExpectations` and `createPipelineExecutor` and public ONLY to be serializable through remote server
2331
+ * Note: Always thrown in `checkExpectations` and catched in `createPipelineExecutor` and rethrown as `PipelineExecutionError`
2332
+ * Note: This is a kindof subtype of PipelineExecutionError
2333
+ */
2334
+ var ExpectError = /** @class */ (function (_super) {
2335
+ __extends(ExpectError, _super);
2336
+ function ExpectError(message) {
2337
+ var _this = _super.call(this, message) || this;
2338
+ _this.name = 'ExpectError';
2339
+ Object.setPrototypeOf(_this, ExpectError.prototype);
2340
+ return _this;
2341
+ }
2342
+ return ExpectError;
2343
+ }(Error));
2948
2344
 
2949
- ${block(warningMessage)}
2950
- `,
2951
- ),
2952
- );
2953
- return [];
2954
- },
2955
- };
2956
- */
2345
+ /**
2346
+ * This error type indicates that some limit was reached
2347
+ *
2348
+ * @public exported from `@promptbook/core`
2349
+ */
2350
+ var LimitReachedError = /** @class */ (function (_super) {
2351
+ __extends(LimitReachedError, _super);
2352
+ function LimitReachedError(message) {
2353
+ var _this = _super.call(this, message) || this;
2354
+ _this.name = 'LimitReachedError';
2355
+ Object.setPrototypeOf(_this, LimitReachedError.prototype);
2356
+ return _this;
2957
2357
  }
2958
- return new (MultipleLlmExecutionTools.bind.apply(MultipleLlmExecutionTools, __spreadArray([void 0], __read(llmExecutionTools), false)))();
2959
- }
2358
+ return LimitReachedError;
2359
+ }(Error));
2360
+
2960
2361
  /**
2961
- * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
2362
+ * This error type indicates that some part of the code is not implemented yet
2363
+ *
2364
+ * @public exported from `@promptbook/core`
2962
2365
  */
2366
+ var NotYetImplementedError = /** @class */ (function (_super) {
2367
+ __extends(NotYetImplementedError, _super);
2368
+ function NotYetImplementedError(message) {
2369
+ var _this = _super.call(this, spaceTrim$1(function (block) { return "\n ".concat(block(message), "\n\n Note: This feature is not implemented yet but it will be soon.\n\n If you want speed up the implementation or just read more, look here:\n https://github.com/webgptorg/promptbook\n\n Or contact us on me@pavolhejny.com\n\n "); })) || this;
2370
+ _this.name = 'NotYetImplementedError';
2371
+ Object.setPrototypeOf(_this, NotYetImplementedError.prototype);
2372
+ return _this;
2373
+ }
2374
+ return NotYetImplementedError;
2375
+ }(Error));
2963
2376
 
2964
2377
  /**
2965
- * Takes an item or an array of items and returns an array of items
2378
+ * Index of all custom errors
2966
2379
  *
2967
- * 1) Any item except array and undefined returns array with that one item (also null)
2968
- * 2) Undefined returns empty array
2969
- * 3) Array returns itself
2380
+ * @public exported from `@promptbook/core`
2381
+ */
2382
+ var ERRORS = {
2383
+ ExpectError: ExpectError,
2384
+ CollectionError: CollectionError,
2385
+ EnvironmentMismatchError: EnvironmentMismatchError,
2386
+ LimitReachedError: LimitReachedError,
2387
+ NotFoundError: NotFoundError,
2388
+ NotYetImplementedError: NotYetImplementedError,
2389
+ ParseError: ParseError,
2390
+ PipelineExecutionError: PipelineExecutionError,
2391
+ PipelineLogicError: PipelineLogicError,
2392
+ PipelineUrlError: PipelineUrlError,
2393
+ UnexpectedError: UnexpectedError,
2394
+ // TODO: [🪑]> VersionMismatchError,
2395
+ };
2396
+
2397
+ /**
2398
+ * Deserializes the error object
2970
2399
  *
2971
- * @private internal utility
2400
+ * @public exported from `@promptbook/utils`
2972
2401
  */
2973
- function arrayableToArray(input) {
2974
- if (input === undefined) {
2975
- return [];
2976
- }
2977
- if (input instanceof Array) {
2978
- return input;
2402
+ function deserializeError(error) {
2403
+ if (error.name === 'Error') {
2404
+ return new Error(error.message);
2979
2405
  }
2980
- return [input];
2406
+ var CustomError = ERRORS[error.name];
2407
+ return new CustomError(error.message);
2981
2408
  }
2982
2409
 
2983
2410
  /**
2984
- * @@@
2411
+ * Asserts that the execution of a Promptbook is successful
2985
2412
  *
2986
- * @public exported from `@promptbook/utils`
2413
+ * @param executionResult - The partial result of the Promptbook execution
2414
+ * @throws {PipelineExecutionError} If the execution is not successful or if multiple errors occurred
2415
+ * @public exported from `@promptbook/core`
2987
2416
  */
2988
- function deepClone(objectValue) {
2989
- return JSON.parse(JSON.stringify(objectValue));
2990
- /*
2991
- TODO: [🧠] Is there a better implementation?
2992
- > const propertyNames = Object.getOwnPropertyNames(objectValue);
2993
- > for (const propertyName of propertyNames) {
2994
- > const value = (objectValue as really_any)[propertyName];
2995
- > if (value && typeof value === 'object') {
2996
- > deepClone(value);
2997
- > }
2998
- > }
2999
- > return Object.assign({}, objectValue);
3000
- */
2417
+ function assertsExecutionSuccessful(executionResult) {
2418
+ var isSuccessful = executionResult.isSuccessful, errors = executionResult.errors;
2419
+ if (isSuccessful === true) {
2420
+ return;
2421
+ }
2422
+ if (errors.length === 0) {
2423
+ throw new PipelineExecutionError("Promptbook Execution failed because of unknown reason");
2424
+ }
2425
+ else if (errors.length === 1) {
2426
+ throw deserializeError(errors[0]);
2427
+ }
2428
+ else {
2429
+ throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Multiple errors occurred during Promptbook execution\n\n ".concat(block(errors
2430
+ .map(function (_a, index) {
2431
+ var name = _a.name, stack = _a.stack, message = _a.message;
2432
+ return spaceTrim$1(function (block) { return "\n ".concat(name, " ").concat(index + 1, ":\n ").concat(block(stack || message), "\n "); });
2433
+ })
2434
+ .join('\n')), "\n "); }));
2435
+ }
3001
2436
  }
3002
2437
  /**
3003
- * TODO: [🧠] Is there a way how to meaningfully test this utility
2438
+ * TODO: [🧠] Can this return type be better typed than void
3004
2439
  */
3005
2440
 
3006
2441
  /**
3007
- * Represents the usage with no resources consumed
2442
+ * Determine if the pipeline is fully prepared
3008
2443
  *
3009
2444
  * @public exported from `@promptbook/core`
3010
2445
  */
3011
- var ZERO_USAGE = $deepFreeze({
3012
- price: { value: 0 },
3013
- input: {
3014
- tokensCount: { value: 0 },
3015
- charactersCount: { value: 0 },
3016
- wordsCount: { value: 0 },
3017
- sentencesCount: { value: 0 },
3018
- linesCount: { value: 0 },
3019
- paragraphsCount: { value: 0 },
3020
- pagesCount: { value: 0 },
3021
- },
3022
- output: {
3023
- tokensCount: { value: 0 },
3024
- charactersCount: { value: 0 },
3025
- wordsCount: { value: 0 },
3026
- sentencesCount: { value: 0 },
3027
- linesCount: { value: 0 },
3028
- paragraphsCount: { value: 0 },
3029
- pagesCount: { value: 0 },
3030
- },
3031
- });
2446
+ function isPipelinePrepared(pipeline) {
2447
+ // Note: Ignoring `pipeline.preparations` @@@
2448
+ // Note: Ignoring `pipeline.knowledgePieces` @@@
2449
+ if (!pipeline.personas.every(function (persona) { return persona.modelRequirements !== undefined; })) {
2450
+ return false;
2451
+ }
2452
+ if (!pipeline.knowledgeSources.every(function (knowledgeSource) { return knowledgeSource.preparationIds !== undefined; })) {
2453
+ return false;
2454
+ }
2455
+ /*
2456
+ TODO: [🧠][🍫] `templates` can not be determined if they are fully prepared SO ignoring them
2457
+ > if (!pipeline.templates.every(({ preparedContent }) => preparedContent === undefined)) {
2458
+ > return false;
2459
+ > }
2460
+ */
2461
+ return true;
2462
+ }
3032
2463
  /**
3033
- * Represents the usage with unknown resources consumed
3034
- *
3035
- * @public exported from `@promptbook/core`
2464
+ * TODO: [🔃][main] !!!!! If the pipeline was prepared with different version or different set of models, prepare it once again
2465
+ * TODO: [🐠] Maybe base this on `makeValidator`
2466
+ * TODO: [🧊] Pipeline can be partially prepared, this should return true ONLY if fully prepared
2467
+ * TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
2468
+ * - [🏍] ? Is context in each template
2469
+ * - [♨] Are samples prepared
2470
+ * - [♨] Are templates prepared
3036
2471
  */
3037
- var UNCERTAIN_USAGE = $deepFreeze({
3038
- price: { value: 0, isUncertain: true },
3039
- input: {
3040
- tokensCount: { value: 0, isUncertain: true },
3041
- charactersCount: { value: 0, isUncertain: true },
3042
- wordsCount: { value: 0, isUncertain: true },
3043
- sentencesCount: { value: 0, isUncertain: true },
3044
- linesCount: { value: 0, isUncertain: true },
3045
- paragraphsCount: { value: 0, isUncertain: true },
3046
- pagesCount: { value: 0, isUncertain: true },
3047
- },
3048
- output: {
3049
- tokensCount: { value: 0, isUncertain: true },
3050
- charactersCount: { value: 0, isUncertain: true },
3051
- wordsCount: { value: 0, isUncertain: true },
3052
- sentencesCount: { value: 0, isUncertain: true },
3053
- linesCount: { value: 0, isUncertain: true },
3054
- paragraphsCount: { value: 0, isUncertain: true },
3055
- pagesCount: { value: 0, isUncertain: true },
3056
- },
3057
- });
3058
2472
 
3059
2473
  /**
3060
- * Function `addUsage` will add multiple usages into one
3061
- *
3062
- * Note: If you provide 0 values, it returns ZERO_USAGE
2474
+ * Serializes an error into a [🚉] JSON-serializable object
3063
2475
  *
3064
- * @public exported from `@promptbook/core`
2476
+ * @public exported from `@promptbook/utils`
3065
2477
  */
3066
- function addUsage() {
3067
- var usageItems = [];
3068
- for (var _i = 0; _i < arguments.length; _i++) {
3069
- usageItems[_i] = arguments[_i];
2478
+ function serializeError(error) {
2479
+ var name = error.name, message = error.message, stack = error.stack;
2480
+ if (!__spreadArray(['Error'], __read(Object.keys(ERRORS)), false).includes(name)) {
2481
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n \n Cannot serialize error with name \"".concat(name, "\"\n\n ").concat(block(stack || message), "\n \n "); }));
3070
2482
  }
3071
- return usageItems.reduce(function (acc, item) {
3072
- var e_1, _a, e_2, _b;
3073
- var _c;
3074
- acc.price.value += ((_c = item.price) === null || _c === void 0 ? void 0 : _c.value) || 0;
3075
- try {
3076
- for (var _d = __values(Object.keys(acc.input)), _e = _d.next(); !_e.done; _e = _d.next()) {
3077
- var key = _e.value;
3078
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3079
- //@ts-ignore
3080
- if (item.input[key]) {
3081
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3082
- //@ts-ignore
3083
- acc.input[key].value += item.input[key].value || 0;
3084
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3085
- //@ts-ignore
3086
- if (item.input[key].isUncertain) {
3087
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3088
- //@ts-ignore
3089
- acc.input[key].isUncertain = true;
3090
- }
3091
- }
3092
- }
3093
- }
3094
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
3095
- finally {
3096
- try {
3097
- if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
3098
- }
3099
- finally { if (e_1) throw e_1.error; }
3100
- }
3101
- try {
3102
- for (var _f = __values(Object.keys(acc.output)), _g = _f.next(); !_g.done; _g = _f.next()) {
3103
- var key = _g.value;
3104
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3105
- //@ts-ignore
3106
- if (item.output[key]) {
3107
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3108
- //@ts-ignore
3109
- acc.output[key].value += item.output[key].value || 0;
3110
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3111
- //@ts-ignore
3112
- if (item.output[key].isUncertain) {
3113
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3114
- //@ts-ignore
3115
- acc.output[key].isUncertain = true;
3116
- }
3117
- }
3118
- }
3119
- }
3120
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
3121
- finally {
3122
- try {
3123
- if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
3124
- }
3125
- finally { if (e_2) throw e_2.error; }
3126
- }
3127
- return acc;
3128
- }, deepClone(ZERO_USAGE));
2483
+ return {
2484
+ name: name,
2485
+ message: message,
2486
+ stack: stack,
2487
+ };
3129
2488
  }
3130
2489
 
3131
2490
  /**
@@ -3333,6 +2692,23 @@ function union() {
3333
2692
  return union;
3334
2693
  }
3335
2694
 
2695
+ /**
2696
+ * Just marks a place of place where should be something implemented
2697
+ * No side effects.
2698
+ *
2699
+ * Note: It can be usefull suppressing eslint errors of unused variables
2700
+ *
2701
+ * @param value any values
2702
+ * @returns void
2703
+ * @private within the repository
2704
+ */
2705
+ function TODO_USE() {
2706
+ var value = [];
2707
+ for (var _i = 0; _i < arguments.length; _i++) {
2708
+ value[_i] = arguments[_i];
2709
+ }
2710
+ }
2711
+
3336
2712
  /**
3337
2713
  * This error indicates problems parsing the format value
3338
2714
  *
@@ -3846,6 +3222,25 @@ function extractJsonBlock(markdown) {
3846
3222
  * TODO: [🏢] Make this logic part of `JsonFormatDefinition` or `isValidJsonString`
3847
3223
  */
3848
3224
 
3225
+ /**
3226
+ * Takes an item or an array of items and returns an array of items
3227
+ *
3228
+ * 1) Any item except array and undefined returns array with that one item (also null)
3229
+ * 2) Undefined returns empty array
3230
+ * 3) Array returns itself
3231
+ *
3232
+ * @private internal utility
3233
+ */
3234
+ function arrayableToArray(input) {
3235
+ if (input === undefined) {
3236
+ return [];
3237
+ }
3238
+ if (input instanceof Array) {
3239
+ return input;
3240
+ }
3241
+ return [input];
3242
+ }
3243
+
3849
3244
  /**
3850
3245
  * Just says that the variable is not used but should be kept
3851
3246
  * No side effects.
@@ -3947,69 +3342,330 @@ function replaceParameters(template, parameters) {
3947
3342
  }
3948
3343
 
3949
3344
  /**
3950
- * Counts number of characters in the text
3345
+ * Counts number of characters in the text
3346
+ *
3347
+ * @public exported from `@promptbook/utils`
3348
+ */
3349
+ function countCharacters(text) {
3350
+ // Remove null characters
3351
+ text = text.replace(/\0/g, '');
3352
+ // Replace emojis (and also ZWJ sequence) with hyphens
3353
+ text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
3354
+ text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
3355
+ text = text.replace(/\p{Extended_Pictographic}(\u{200D}\p{Extended_Pictographic})*/gu, '-');
3356
+ return text.length;
3357
+ }
3358
+
3359
+ /**
3360
+ * Counts number of lines in the text
3361
+ *
3362
+ * @public exported from `@promptbook/utils`
3363
+ */
3364
+ function countLines(text) {
3365
+ if (text === '') {
3366
+ return 0;
3367
+ }
3368
+ return text.split('\n').length;
3369
+ }
3370
+
3371
+ /**
3372
+ * Counts number of pages in the text
3373
+ *
3374
+ * @public exported from `@promptbook/utils`
3375
+ */
3376
+ function countPages(text) {
3377
+ var sentencesPerPage = 5; // Assuming each page has 5 sentences
3378
+ var sentences = text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
3379
+ var pageCount = Math.ceil(sentences.length / sentencesPerPage);
3380
+ return pageCount;
3381
+ }
3382
+
3383
+ /**
3384
+ * Counts number of paragraphs in the text
3385
+ *
3386
+ * @public exported from `@promptbook/utils`
3387
+ */
3388
+ function countParagraphs(text) {
3389
+ return text.split(/\n\s*\n/).filter(function (paragraph) { return paragraph.trim() !== ''; }).length;
3390
+ }
3391
+
3392
+ /**
3393
+ * Split text into sentences
3394
+ *
3395
+ * @public exported from `@promptbook/utils`
3396
+ */
3397
+ function splitIntoSentences(text) {
3398
+ return text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
3399
+ }
3400
+ /**
3401
+ * Counts number of sentences in the text
3402
+ *
3403
+ * @public exported from `@promptbook/utils`
3404
+ */
3405
+ function countSentences(text) {
3406
+ return splitIntoSentences(text).length;
3407
+ }
3408
+
3409
+ var defaultDiacriticsRemovalMap = [
3410
+ {
3411
+ base: 'A',
3412
+ letters: '\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F',
3413
+ },
3414
+ { base: 'AA', letters: '\uA732' },
3415
+ { base: 'AE', letters: '\u00C6\u01FC\u01E2' },
3416
+ { base: 'AO', letters: '\uA734' },
3417
+ { base: 'AU', letters: '\uA736' },
3418
+ { base: 'AV', letters: '\uA738\uA73A' },
3419
+ { base: 'AY', letters: '\uA73C' },
3420
+ {
3421
+ base: 'B',
3422
+ letters: '\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181',
3423
+ },
3424
+ {
3425
+ base: 'C',
3426
+ letters: '\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E',
3427
+ },
3428
+ {
3429
+ base: 'D',
3430
+ letters: '\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779\u00D0',
3431
+ },
3432
+ { base: 'DZ', letters: '\u01F1\u01C4' },
3433
+ { base: 'Dz', letters: '\u01F2\u01C5' },
3434
+ {
3435
+ base: 'E',
3436
+ letters: '\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E',
3437
+ },
3438
+ { base: 'F', letters: '\u0046\u24BB\uFF26\u1E1E\u0191\uA77B' },
3439
+ {
3440
+ base: 'G',
3441
+ letters: '\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E',
3442
+ },
3443
+ {
3444
+ base: 'H',
3445
+ letters: '\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D',
3446
+ },
3447
+ {
3448
+ base: 'I',
3449
+ letters: '\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197',
3450
+ },
3451
+ { base: 'J', letters: '\u004A\u24BF\uFF2A\u0134\u0248' },
3452
+ {
3453
+ base: 'K',
3454
+ letters: '\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2',
3455
+ },
3456
+ {
3457
+ base: 'L',
3458
+ letters: '\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780',
3459
+ },
3460
+ { base: 'LJ', letters: '\u01C7' },
3461
+ { base: 'Lj', letters: '\u01C8' },
3462
+ { base: 'M', letters: '\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C' },
3463
+ {
3464
+ base: 'N',
3465
+ letters: '\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4',
3466
+ },
3467
+ { base: 'NJ', letters: '\u01CA' },
3468
+ { base: 'Nj', letters: '\u01CB' },
3469
+ {
3470
+ base: 'O',
3471
+ letters: '\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C',
3472
+ },
3473
+ { base: 'OI', letters: '\u01A2' },
3474
+ { base: 'OO', letters: '\uA74E' },
3475
+ { base: 'OU', letters: '\u0222' },
3476
+ { base: 'OE', letters: '\u008C\u0152' },
3477
+ { base: 'oe', letters: '\u009C\u0153' },
3478
+ {
3479
+ base: 'P',
3480
+ letters: '\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754',
3481
+ },
3482
+ { base: 'Q', letters: '\u0051\u24C6\uFF31\uA756\uA758\u024A' },
3483
+ {
3484
+ base: 'R',
3485
+ letters: '\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782',
3486
+ },
3487
+ {
3488
+ base: 'S',
3489
+ letters: '\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784',
3490
+ },
3491
+ {
3492
+ base: 'T',
3493
+ letters: '\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786',
3494
+ },
3495
+ { base: 'TZ', letters: '\uA728' },
3496
+ {
3497
+ base: 'U',
3498
+ letters: '\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244',
3499
+ },
3500
+ { base: 'V', letters: '\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245' },
3501
+ { base: 'VY', letters: '\uA760' },
3502
+ {
3503
+ base: 'W',
3504
+ letters: '\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72',
3505
+ },
3506
+ { base: 'X', letters: '\u0058\u24CD\uFF38\u1E8A\u1E8C' },
3507
+ {
3508
+ base: 'Y',
3509
+ letters: '\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE',
3510
+ },
3511
+ {
3512
+ base: 'Z',
3513
+ letters: '\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762',
3514
+ },
3515
+ {
3516
+ base: 'a',
3517
+ letters: '\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250',
3518
+ },
3519
+ { base: 'aa', letters: '\uA733' },
3520
+ { base: 'ae', letters: '\u00E6\u01FD\u01E3' },
3521
+ { base: 'ao', letters: '\uA735' },
3522
+ { base: 'au', letters: '\uA737' },
3523
+ { base: 'av', letters: '\uA739\uA73B' },
3524
+ { base: 'ay', letters: '\uA73D' },
3525
+ {
3526
+ base: 'b',
3527
+ letters: '\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253',
3528
+ },
3529
+ {
3530
+ base: 'c',
3531
+ letters: '\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184',
3532
+ },
3533
+ {
3534
+ base: 'd',
3535
+ letters: '\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A',
3536
+ },
3537
+ { base: 'dz', letters: '\u01F3\u01C6' },
3538
+ {
3539
+ base: 'e',
3540
+ letters: '\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD',
3541
+ },
3542
+ { base: 'f', letters: '\u0066\u24D5\uFF46\u1E1F\u0192\uA77C' },
3543
+ {
3544
+ base: 'g',
3545
+ letters: '\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F',
3546
+ },
3547
+ {
3548
+ base: 'h',
3549
+ letters: '\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265',
3550
+ },
3551
+ { base: 'hv', letters: '\u0195' },
3552
+ {
3553
+ base: 'i',
3554
+ letters: '\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131',
3555
+ },
3556
+ { base: 'j', letters: '\u006A\u24D9\uFF4A\u0135\u01F0\u0249' },
3557
+ {
3558
+ base: 'k',
3559
+ letters: '\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3',
3560
+ },
3561
+ {
3562
+ base: 'l',
3563
+ letters: '\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747',
3564
+ },
3565
+ { base: 'lj', letters: '\u01C9' },
3566
+ { base: 'm', letters: '\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F' },
3567
+ {
3568
+ base: 'n',
3569
+ letters: '\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5',
3570
+ },
3571
+ { base: 'nj', letters: '\u01CC' },
3572
+ {
3573
+ base: 'o',
3574
+ letters: '\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275',
3575
+ },
3576
+ { base: 'oi', letters: '\u01A3' },
3577
+ { base: 'ou', letters: '\u0223' },
3578
+ { base: 'oo', letters: '\uA74F' },
3579
+ {
3580
+ base: 'p',
3581
+ letters: '\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755',
3582
+ },
3583
+ { base: 'q', letters: '\u0071\u24E0\uFF51\u024B\uA757\uA759' },
3584
+ {
3585
+ base: 'r',
3586
+ letters: '\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783',
3587
+ },
3588
+ {
3589
+ base: 's',
3590
+ letters: '\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B',
3591
+ },
3592
+ {
3593
+ base: 't',
3594
+ letters: '\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787',
3595
+ },
3596
+ { base: 'tz', letters: '\uA729' },
3597
+ {
3598
+ base: 'u',
3599
+ letters: '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289',
3600
+ },
3601
+ { base: 'v', letters: '\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C' },
3602
+ { base: 'vy', letters: '\uA761' },
3603
+ {
3604
+ base: 'w',
3605
+ letters: '\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73',
3606
+ },
3607
+ { base: 'x', letters: '\u0078\u24E7\uFF58\u1E8B\u1E8D' },
3608
+ {
3609
+ base: 'y',
3610
+ letters: '\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF',
3611
+ },
3612
+ {
3613
+ base: 'z',
3614
+ letters: '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763',
3615
+ },
3616
+ ];
3617
+ /**
3618
+ * Map of letters from diacritic variant to diacritless variant
3619
+ * Contains lowercase and uppercase separatelly
3951
3620
  *
3952
- * @public exported from `@promptbook/utils`
3953
- */
3954
- function countCharacters(text) {
3955
- // Remove null characters
3956
- text = text.replace(/\0/g, '');
3957
- // Replace emojis (and also ZWJ sequence) with hyphens
3958
- text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
3959
- text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
3960
- text = text.replace(/\p{Extended_Pictographic}(\u{200D}\p{Extended_Pictographic})*/gu, '-');
3961
- return text.length;
3962
- }
3963
-
3964
- /**
3965
- * Counts number of lines in the text
3621
+ * > "á" => "a"
3622
+ * > "ě" => "e"
3623
+ * > "Ă" => "A"
3624
+ * > ...
3966
3625
  *
3967
3626
  * @public exported from `@promptbook/utils`
3968
3627
  */
3969
- function countLines(text) {
3970
- if (text === '') {
3971
- return 0;
3628
+ var DIACRITIC_VARIANTS_LETTERS = {};
3629
+ // tslint:disable-next-line: prefer-for-of
3630
+ for (var i = 0; i < defaultDiacriticsRemovalMap.length; i++) {
3631
+ var letters = defaultDiacriticsRemovalMap[i].letters;
3632
+ // tslint:disable-next-line: prefer-for-of
3633
+ for (var j = 0; j < letters.length; j++) {
3634
+ DIACRITIC_VARIANTS_LETTERS[letters[j]] = defaultDiacriticsRemovalMap[i].base;
3972
3635
  }
3973
- return text.split('\n').length;
3974
3636
  }
3637
+ // <- TODO: [🍓] Put to maker function to save execution time if not needed
3638
+ /*
3639
+ @see https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript
3640
+ Licensed under the Apache License, Version 2.0 (the "License");
3641
+ you may not use this file except in compliance with the License.
3642
+ You may obtain a copy of the License at
3975
3643
 
3976
- /**
3977
- * Counts number of pages in the text
3978
- *
3979
- * @public exported from `@promptbook/utils`
3980
- */
3981
- function countPages(text) {
3982
- var sentencesPerPage = 5; // Assuming each page has 5 sentences
3983
- var sentences = text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
3984
- var pageCount = Math.ceil(sentences.length / sentencesPerPage);
3985
- return pageCount;
3986
- }
3644
+ http://www.apache.org/licenses/LICENSE-2.0
3987
3645
 
3988
- /**
3989
- * Counts number of paragraphs in the text
3990
- *
3991
- * @public exported from `@promptbook/utils`
3992
- */
3993
- function countParagraphs(text) {
3994
- return text.split(/\n\s*\n/).filter(function (paragraph) { return paragraph.trim() !== ''; }).length;
3995
- }
3646
+ Unless required by applicable law or agreed to in writing, software
3647
+ distributed under the License is distributed on an "AS IS" BASIS,
3648
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3649
+ See the License for the specific language governing permissions and
3650
+ limitations under the License.
3651
+ */
3996
3652
 
3997
3653
  /**
3998
- * Split text into sentences
3654
+ * @@@
3999
3655
  *
3656
+ * @param input @@@
3657
+ * @returns @@@
4000
3658
  * @public exported from `@promptbook/utils`
4001
3659
  */
4002
- function splitIntoSentences(text) {
4003
- return text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
3660
+ function removeDiacritics(input) {
3661
+ /*eslint no-control-regex: "off"*/
3662
+ return input.replace(/[^\u0000-\u007E]/g, function (a) {
3663
+ return DIACRITIC_VARIANTS_LETTERS[a] || a;
3664
+ });
4004
3665
  }
4005
3666
  /**
4006
- * Counts number of sentences in the text
4007
- *
4008
- * @public exported from `@promptbook/utils`
3667
+ * TODO: [Ж] Variant for cyrillic (and in general non-latin) letters
4009
3668
  */
4010
- function countSentences(text) {
4011
- return splitIntoSentences(text).length;
4012
- }
4013
3669
 
4014
3670
  /**
4015
3671
  * Counts number of words in the text
@@ -4107,11 +3763,11 @@ function isPassingExpectations(expectations, value) {
4107
3763
  */
4108
3764
  function executeAttempts(options) {
4109
3765
  return __awaiter(this, void 0, void 0, function () {
4110
- var jokerParameterNames, priority, maxAttempts, preparedContent, parameters, template, preparedPipeline, tools, llmTools, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, $ongoingTemplateResult, _loop_1, attempt, state_1;
3766
+ var jokerParameterNames, priority, maxAttempts, preparedContent, parameters, template, preparedPipeline, tools, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, $ongoingTemplateResult, _llms, llmTools, _loop_1, attempt, state_1;
4111
3767
  return __generator(this, function (_a) {
4112
3768
  switch (_a.label) {
4113
3769
  case 0:
4114
- jokerParameterNames = options.jokerParameterNames, priority = options.priority, maxAttempts = options.maxAttempts, preparedContent = options.preparedContent, parameters = options.parameters, template = options.template, preparedPipeline = options.preparedPipeline, tools = options.tools, llmTools = options.llmTools, settings = options.settings, $executionReport = options.$executionReport, pipelineIdentification = options.pipelineIdentification;
3770
+ jokerParameterNames = options.jokerParameterNames, priority = options.priority, maxAttempts = options.maxAttempts, preparedContent = options.preparedContent, parameters = options.parameters, template = options.template, preparedPipeline = options.preparedPipeline, tools = options.tools, settings = options.settings, $executionReport = options.$executionReport, pipelineIdentification = options.pipelineIdentification;
4115
3771
  maxExecutionAttempts = settings.maxExecutionAttempts;
4116
3772
  $ongoingTemplateResult = {
4117
3773
  $result: null,
@@ -4119,6 +3775,8 @@ function executeAttempts(options) {
4119
3775
  $expectError: null,
4120
3776
  $scriptPipelineExecutionErrors: [],
4121
3777
  };
3778
+ _llms = arrayableToArray(tools.llm);
3779
+ llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools.apply(void 0, __spreadArray([], __read(_llms), false));
4122
3780
  _loop_1 = function (attempt) {
4123
3781
  var isJokerAttempt, jokerParameterName, _b, modelRequirements, _c, _d, _e, _f, _g, scriptTools, _h, error_1, e_1_1, _j, _k, _l, functionName, postprocessingError, _m, _o, scriptTools, _p, error_2, e_2_1, e_3_1, error_3;
4124
3782
  var e_1, _q, e_3, _r, e_2, _s;
@@ -4187,7 +3845,9 @@ function executeAttempts(options) {
4187
3845
  return [3 /*break*/, 9];
4188
3846
  case 4:
4189
3847
  _d = $ongoingTemplateResult;
4190
- return [4 /*yield*/, llmTools.callChatModel($deepFreeze($ongoingTemplateResult.$prompt))];
3848
+ return [4 /*yield*/, llmTools.callChatModel(
3849
+ // <- TODO: [🧁] Check that `callChatModel` is defined
3850
+ $deepFreeze($ongoingTemplateResult.$prompt))];
4191
3851
  case 5:
4192
3852
  _d.$chatResult = _t.sent();
4193
3853
  // TODO: [🍬] Destroy chatThread
@@ -4196,7 +3856,9 @@ function executeAttempts(options) {
4196
3856
  return [3 /*break*/, 10];
4197
3857
  case 6:
4198
3858
  _e = $ongoingTemplateResult;
4199
- return [4 /*yield*/, llmTools.callCompletionModel($deepFreeze($ongoingTemplateResult.$prompt))];
3859
+ return [4 /*yield*/, llmTools.callCompletionModel(
3860
+ // <- TODO: [🧁] Check that `callCompletionModel` is defined
3861
+ $deepFreeze($ongoingTemplateResult.$prompt))];
4200
3862
  case 7:
4201
3863
  _e.$completionResult = _t.sent();
4202
3864
  $ongoingTemplateResult.$result = $ongoingTemplateResult.$completionResult;
@@ -4660,12 +4322,12 @@ function getReservedParametersForTemplate(options) {
4660
4322
  */
4661
4323
  function executeTemplate(options) {
4662
4324
  return __awaiter(this, void 0, void 0, function () {
4663
- var currentTemplate, preparedPipeline, parametersToPass, tools, llmTools, onProgress, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, name, title, priority, usedParameterNames, dependentParameterNames, definedParameters, _a, _b, _c, definedParameterNames, parameters, _loop_1, _d, _e, parameterName, maxAttempts, jokerParameterNames, preparedContent, resultString;
4325
+ var currentTemplate, preparedPipeline, parametersToPass, tools, onProgress, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, name, title, priority, usedParameterNames, dependentParameterNames, definedParameters, _a, _b, _c, definedParameterNames, parameters, _loop_1, _d, _e, parameterName, maxAttempts, jokerParameterNames, preparedContent, resultString;
4664
4326
  var e_1, _f, _g;
4665
4327
  return __generator(this, function (_h) {
4666
4328
  switch (_h.label) {
4667
4329
  case 0:
4668
- currentTemplate = options.currentTemplate, preparedPipeline = options.preparedPipeline, parametersToPass = options.parametersToPass, tools = options.tools, llmTools = options.llmTools, onProgress = options.onProgress, settings = options.settings, $executionReport = options.$executionReport, pipelineIdentification = options.pipelineIdentification;
4330
+ currentTemplate = options.currentTemplate, preparedPipeline = options.preparedPipeline, parametersToPass = options.parametersToPass, tools = options.tools, onProgress = options.onProgress, settings = options.settings, $executionReport = options.$executionReport, pipelineIdentification = options.pipelineIdentification;
4669
4331
  maxExecutionAttempts = settings.maxExecutionAttempts;
4670
4332
  name = "pipeline-executor-frame-".concat(currentTemplate.name);
4671
4333
  title = currentTemplate.title;
@@ -4748,7 +4410,6 @@ function executeTemplate(options) {
4748
4410
  template: currentTemplate,
4749
4411
  preparedPipeline: preparedPipeline,
4750
4412
  tools: tools,
4751
- llmTools: llmTools,
4752
4413
  settings: settings,
4753
4414
  $executionReport: $executionReport,
4754
4415
  pipelineIdentification: pipelineIdentification,
@@ -4830,7 +4491,7 @@ function filterJustOutputParameters(options) {
4830
4491
  */
4831
4492
  function executePipeline(options) {
4832
4493
  return __awaiter(this, void 0, void 0, function () {
4833
- var inputParameters, tools, onProgress, pipeline, setPreparedPipeline, pipelineIdentification, settings, maxParallelCount, rootDirname, _a, isVerbose, preparedPipeline, llmTools, errors, warnings, executionReport, isReturned, _b, _c, parameter, e_1_1, _loop_1, _d, _e, parameterName, state_1, e_2_1, parametersToPass, resovedParameterNames_1, unresovedTemplates_1, resolving_1, loopLimit, _loop_2, error_1, usage_1, outputParameters_1, usage, outputParameters;
4494
+ var inputParameters, tools, onProgress, pipeline, setPreparedPipeline, pipelineIdentification, settings, maxParallelCount, rootDirname, _a, isVerbose, preparedPipeline, errors, warnings, executionReport, isReturned, _b, _c, parameter, e_1_1, _loop_1, _d, _e, parameterName, state_1, e_2_1, parametersToPass, resovedParameterNames_1, unresovedTemplates_1, resolving_1, loopLimit, _loop_2, error_1, usage_1, outputParameters_1, usage, outputParameters;
4834
4495
  var e_1, _f, e_2, _g;
4835
4496
  return __generator(this, function (_h) {
4836
4497
  switch (_h.label) {
@@ -4838,10 +4499,8 @@ function executePipeline(options) {
4838
4499
  inputParameters = options.inputParameters, tools = options.tools, onProgress = options.onProgress, pipeline = options.pipeline, setPreparedPipeline = options.setPreparedPipeline, pipelineIdentification = options.pipelineIdentification, settings = options.settings;
4839
4500
  maxParallelCount = settings.maxParallelCount, rootDirname = settings.rootDirname, _a = settings.isVerbose, isVerbose = _a === void 0 ? IS_VERBOSE : _a;
4840
4501
  preparedPipeline = options.preparedPipeline;
4841
- llmTools = joinLlmExecutionTools.apply(void 0, __spreadArray([], __read(arrayableToArray(tools.llm)), false));
4842
4502
  if (!(preparedPipeline === undefined)) return [3 /*break*/, 2];
4843
- return [4 /*yield*/, preparePipeline(pipeline, {
4844
- llmTools: llmTools,
4503
+ return [4 /*yield*/, preparePipeline(pipeline, tools, {
4845
4504
  rootDirname: rootDirname,
4846
4505
  isVerbose: isVerbose,
4847
4506
  maxParallelCount: maxParallelCount,
@@ -5028,7 +4687,6 @@ function executePipeline(options) {
5028
4687
  preparedPipeline: preparedPipeline,
5029
4688
  parametersToPass: parametersToPass,
5030
4689
  tools: tools,
5031
- llmTools: llmTools,
5032
4690
  onProgress: function (progress) {
5033
4691
  if (isReturned) {
5034
4692
  throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Can not call `onProgress` after pipeline execution is finished\n\n ".concat(block(pipelineIdentification), "\n\n ").concat(block(JSON.stringify(progress, null, 4)
@@ -5200,631 +4858,412 @@ function createPipelineExecutor(options) {
5200
4858
  */
5201
4859
 
5202
4860
  /**
5203
- * Scraper for markdown files
4861
+ * Prepares the persona for the pipeline
5204
4862
  *
5205
- * @see `documentationUrl` for more details
4863
+ * @see https://github.com/webgptorg/promptbook/discussions/22
5206
4864
  * @public exported from `@promptbook/core`
5207
4865
  */
5208
- var markdownScraper = {
5209
- /**
5210
- * Mime types that this scraper can handle
5211
- */
5212
- mimeTypes: ['text/markdown', 'text/plain'],
5213
- /**
5214
- * Link to documentation
5215
- */
5216
- documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
5217
- /**
5218
- * Scrapes the markdown file and returns the knowledge pieces or `null` if it can't scrape it
5219
- */
5220
- scrape: function (source, options) {
5221
- return __awaiter(this, void 0, void 0, function () {
5222
- var llmTools, _a, maxParallelCount, _b, isVerbose, collection, prepareKnowledgeFromMarkdownExecutor, _c, prepareTitleExecutor, _d, prepareKeywordsExecutor, _e, knowledgeContent, result, outputParameters, knowledgePiecesRaw, knowledgeTextPieces, knowledge;
5223
- var _f, _g, _h;
5224
- var _this = this;
5225
- return __generator(this, function (_j) {
5226
- switch (_j.label) {
5227
- case 0:
5228
- llmTools = options.llmTools, _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? MAX_PARALLEL_COUNT : _a, _b = options.isVerbose, isVerbose = _b === void 0 ? IS_VERBOSE : _b;
5229
- if (llmTools === undefined) {
5230
- throw new MissingToolsError('LLM tools are required for scraping external files');
5231
- // <- Note: This scraper is used in all other scrapers, so saying "external files" not "markdown files"
5232
- }
5233
- TODO_USE(maxParallelCount); // <- [🪂]
5234
- collection = createCollectionFromJson.apply(void 0, __spreadArray([], __read(PipelineCollection), false));
5235
- _c = createPipelineExecutor;
5236
- _f = {};
5237
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md')];
5238
- case 1:
5239
- prepareKnowledgeFromMarkdownExecutor = _c.apply(void 0, [(_f.pipeline = _j.sent(),
5240
- _f.tools = {
5241
- llm: llmTools,
5242
- },
5243
- _f)]);
5244
- _d = createPipelineExecutor;
5245
- _g = {};
5246
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md')];
5247
- case 2:
5248
- prepareTitleExecutor = _d.apply(void 0, [(_g.pipeline = _j.sent(),
5249
- _g.tools = {
5250
- llm: llmTools,
5251
- },
5252
- _g)]);
5253
- _e = createPipelineExecutor;
5254
- _h = {};
5255
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md')];
5256
- case 3:
5257
- prepareKeywordsExecutor = _e.apply(void 0, [(_h.pipeline = _j.sent(),
5258
- _h.tools = {
5259
- llm: llmTools,
5260
- },
5261
- _h)]);
5262
- return [4 /*yield*/, source.asText()];
5263
- case 4:
5264
- knowledgeContent = _j.sent();
5265
- return [4 /*yield*/, prepareKnowledgeFromMarkdownExecutor({ knowledgeContent: knowledgeContent })];
5266
- case 5:
5267
- result = _j.sent();
5268
- assertsExecutionSuccessful(result);
5269
- outputParameters = result.outputParameters;
5270
- knowledgePiecesRaw = outputParameters.knowledgePieces;
5271
- knowledgeTextPieces = (knowledgePiecesRaw || '').split('\n---\n');
5272
- // <- TODO: [main] !!!!! Smarter split and filter out empty pieces
5273
- if (isVerbose) {
5274
- console.info('knowledgeTextPieces:', knowledgeTextPieces);
5275
- }
5276
- return [4 /*yield*/, Promise.all(
5277
- // TODO: [🪂] !! Do not send all at once but in chunks
5278
- knowledgeTextPieces.map(function (knowledgeTextPiece, i) { return __awaiter(_this, void 0, void 0, function () {
5279
- var name, title, knowledgePieceContent, keywords, index, titleResult, _a, titleRaw, keywordsResult, _b, keywordsRaw, embeddingResult, error_1;
5280
- return __generator(this, function (_c) {
5281
- switch (_c.label) {
5282
- case 0:
5283
- name = "piece-".concat(i);
5284
- title = spaceTrim(knowledgeTextPiece.substring(0, 100));
5285
- knowledgePieceContent = spaceTrim(knowledgeTextPiece);
5286
- keywords = [];
5287
- index = [];
5288
- _c.label = 1;
5289
- case 1:
5290
- _c.trys.push([1, 7, , 8]);
5291
- return [4 /*yield*/, prepareTitleExecutor({ knowledgePieceContent: knowledgePieceContent })];
5292
- case 2:
5293
- titleResult = _c.sent();
5294
- _a = titleResult.outputParameters.title, titleRaw = _a === void 0 ? 'Untitled' : _a;
5295
- title = spaceTrim(titleRaw) /* <- TODO: Maybe do in pipeline */;
5296
- name = titleToName(title);
5297
- return [4 /*yield*/, prepareKeywordsExecutor({ knowledgePieceContent: knowledgePieceContent })];
5298
- case 3:
5299
- keywordsResult = _c.sent();
5300
- _b = keywordsResult.outputParameters.keywords, keywordsRaw = _b === void 0 ? '' : _b;
5301
- keywords = (keywordsRaw || '')
5302
- .split(',')
5303
- .map(function (keyword) { return keyword.trim(); })
5304
- .filter(function (keyword) { return keyword !== ''; });
5305
- if (isVerbose) {
5306
- console.info("Keywords for \"".concat(title, "\":"), keywords);
5307
- }
5308
- if (!!llmTools.callEmbeddingModel) return [3 /*break*/, 4];
5309
- // TODO: [🟥] Detect browser / node and make it colorfull
5310
- console.error('No callEmbeddingModel function provided');
5311
- return [3 /*break*/, 6];
5312
- case 4: return [4 /*yield*/, llmTools.callEmbeddingModel({
5313
- title: "Embedding for ".concat(title) /* <- Note: No impact on embedding result itself, just for logging */,
5314
- parameters: {},
5315
- content: knowledgePieceContent,
5316
- modelRequirements: {
5317
- modelVariant: 'EMBEDDING',
5318
- },
5319
- })];
5320
- case 5:
5321
- embeddingResult = _c.sent();
5322
- index.push({
5323
- modelName: embeddingResult.modelName,
5324
- position: embeddingResult.content,
5325
- });
5326
- _c.label = 6;
5327
- case 6: return [3 /*break*/, 8];
5328
- case 7:
5329
- error_1 = _c.sent();
5330
- // Note: Here is expected error:
5331
- // > PipelineExecutionError: You have not provided any `LlmExecutionTools` that support model variant "EMBEDDING
5332
- if (!(error_1 instanceof PipelineExecutionError)) {
5333
- throw error_1;
5334
- }
5335
- // TODO: [🟥] Detect browser / node and make it colorfull
5336
- console.error(error_1, "<- Note: This error is not critical to prepare the pipeline, just knowledge pieces won't have embeddings");
5337
- return [3 /*break*/, 8];
5338
- case 8: return [2 /*return*/, {
5339
- name: name,
5340
- title: title,
5341
- content: knowledgePieceContent,
5342
- keywords: keywords,
5343
- index: index,
5344
- // <- TODO: [☀] sources,
5345
- }];
5346
- }
5347
- });
5348
- }); }))];
5349
- case 6:
5350
- knowledge = _j.sent();
5351
- return [2 /*return*/, knowledge];
5352
- }
5353
- });
4866
+ function preparePersona(personaDescription, tools, options) {
4867
+ return __awaiter(this, void 0, void 0, function () {
4868
+ var _a, isVerbose, collection, preparePersonaExecutor, _b, _llms, llmTools, availableModels, availableModelNames, result, outputParameters, modelRequirementsRaw, modelRequirements, modelName, systemMessage, temperature;
4869
+ var _c;
4870
+ return __generator(this, function (_d) {
4871
+ switch (_d.label) {
4872
+ case 0:
4873
+ _a = options.isVerbose, isVerbose = _a === void 0 ? IS_VERBOSE : _a;
4874
+ if (tools === undefined || tools.llm === undefined) {
4875
+ throw new MissingToolsError('LLM tools are required for preparing persona');
4876
+ }
4877
+ collection = createCollectionFromJson.apply(void 0, __spreadArray([], __read(PipelineCollection), false));
4878
+ _b = createPipelineExecutor;
4879
+ _c = {};
4880
+ return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-persona.ptbk.md')];
4881
+ case 1:
4882
+ preparePersonaExecutor = _b.apply(void 0, [(_c.pipeline = _d.sent(),
4883
+ _c.tools = tools,
4884
+ _c)]);
4885
+ _llms = arrayableToArray(tools.llm);
4886
+ llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools.apply(void 0, __spreadArray([], __read(_llms), false));
4887
+ return [4 /*yield*/, llmTools.listModels()];
4888
+ case 2:
4889
+ availableModels = _d.sent();
4890
+ availableModelNames = availableModels
4891
+ .filter(function (_a) {
4892
+ var modelVariant = _a.modelVariant;
4893
+ return modelVariant === 'CHAT';
4894
+ })
4895
+ .map(function (_a) {
4896
+ var modelName = _a.modelName;
4897
+ return modelName;
4898
+ })
4899
+ .join(',');
4900
+ return [4 /*yield*/, preparePersonaExecutor({ availableModelNames: availableModelNames, personaDescription: personaDescription })];
4901
+ case 3:
4902
+ result = _d.sent();
4903
+ assertsExecutionSuccessful(result);
4904
+ outputParameters = result.outputParameters;
4905
+ modelRequirementsRaw = outputParameters.modelRequirements;
4906
+ modelRequirements = JSON.parse(modelRequirementsRaw);
4907
+ if (isVerbose) {
4908
+ console.info("PERSONA ".concat(personaDescription), modelRequirements);
4909
+ }
4910
+ modelName = modelRequirements.modelName, systemMessage = modelRequirements.systemMessage, temperature = modelRequirements.temperature;
4911
+ return [2 /*return*/, {
4912
+ modelVariant: 'CHAT',
4913
+ modelName: modelName,
4914
+ systemMessage: systemMessage,
4915
+ temperature: temperature,
4916
+ }];
4917
+ }
5354
4918
  });
5355
- },
5356
- } /* TODO: [🦷] as const */;
4919
+ });
4920
+ }
5357
4921
  /**
5358
- * TODO: [🦖] Make some system for putting scrapers to separete packages
5359
- * TODO: [🪂] Do it in parallel 11:11
5360
- * TODO: [🦷] Ideally use `as const satisfies Scraper` BUT this combination throws errors
5361
- * Note: No need to aggregate usage here, it is done by intercepting the llmTools
4922
+ * TODO: [🔃][main] !!!!! If the persona was prepared with different version or different set of models, prepare it once again
4923
+ * TODO: [🏢] !! Check validity of `modelName` in pipeline
4924
+ * TODO: [🏢] !! Check validity of `systemMessage` in pipeline
4925
+ * TODO: [🏢] !! Check validity of `temperature` in pipeline
5362
4926
  */
5363
4927
 
5364
4928
  /**
5365
- * Scraper of .docx and .odt files
4929
+ * This error indicates that the promptbook can not retrieve knowledge from external sources
5366
4930
  *
5367
- * @see `documentationUrl` for more details
5368
4931
  * @public exported from `@promptbook/core`
5369
4932
  */
5370
- var documentScraper = {
5371
- /**
5372
- * Mime types that this scraper can handle
5373
- */
5374
- mimeTypes: ['application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
5375
- /**
5376
- * Link to documentation
5377
- */
5378
- documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
5379
- /**
5380
- * Convert the `.docx` or `.odt` to `.md` file and returns intermediate source
5381
- *
5382
- * Note: `$` is used to indicate that this function is not a pure function - it leaves files on the disk and you are responsible for cleaning them by calling `destroy` method of returned object
5383
- */
5384
- $convert: function (source, options) {
5385
- return __awaiter(this, void 0, void 0, function () {
5386
- var _a, externalProgramsPaths, rootDirname, _b, cacheDirname, _c, isCacheCleaned, _d, isVerbose, extension, cacheFilehandler, command_1;
5387
- return __generator(this, function (_e) {
5388
- switch (_e.label) {
5389
- case 0:
5390
- _a = options.externalProgramsPaths, externalProgramsPaths = _a === void 0 ? {} : _a, rootDirname = options.rootDirname, _b = options.cacheDirname, cacheDirname = _b === void 0 ? SCRAPE_CACHE_DIRNAME : _b, _c = options.isCacheCleaned, isCacheCleaned = _c === void 0 ? false : _c, _d = options.isVerbose, isVerbose = _d === void 0 ? IS_VERBOSE : _d;
5391
- if (!$isRunningInNode()) {
5392
- throw new KnowledgeScrapeError('Scraping .docx files is only supported in Node environment');
5393
- }
5394
- if (externalProgramsPaths.pandocPath === undefined) {
5395
- throw new MissingToolsError('Pandoc is required for scraping .docx files');
5396
- }
5397
- if (source.filename === null) {
5398
- // TODO: [🧠] Maybe save file as temporary
5399
- throw new KnowledgeScrapeError('When parsing .docx file, it must be real file in the file system');
5400
- }
5401
- extension = getFileExtension(source.filename);
5402
- return [4 /*yield*/, getScraperIntermediateSource(source, {
5403
- rootDirname: rootDirname,
5404
- cacheDirname: cacheDirname,
5405
- isCacheCleaned: isCacheCleaned,
5406
- extension: 'md',
5407
- isVerbose: isVerbose,
5408
- })];
5409
- case 1:
5410
- cacheFilehandler = _e.sent();
5411
- return [4 /*yield*/, $isFileExisting(cacheFilehandler.filename)];
5412
- case 2:
5413
- if (!!(_e.sent())) return [3 /*break*/, 5];
5414
- command_1 = "\"".concat(externalProgramsPaths.pandocPath, "\" -f ").concat(extension, " -t markdown \"").concat(source.filename, "\" -o \"").concat(cacheFilehandler.filename, "\"");
5415
- // TODO: !!!!!! [🕊] Make execCommand standard (?node-)util of the promptbook
5416
- return [4 /*yield*/, $execCommand(command_1)];
5417
- case 3:
5418
- // TODO: !!!!!! [🕊] Make execCommand standard (?node-)util of the promptbook
5419
- _e.sent();
5420
- return [4 /*yield*/, $isFileExisting(cacheFilehandler.filename)];
5421
- case 4:
5422
- // Note: [0]
5423
- if (!(_e.sent())) {
5424
- throw new UnexpectedError(spaceTrim(function (block) { return "\n File that was supposed to be created by Pandoc does not exist for unknown reason\n\n Expected file:\n ".concat(block(cacheFilehandler.filename), "\n\n Command:\n > ").concat(block(command_1), "\n\n "); }));
5425
- }
5426
- _e.label = 5;
5427
- case 5: return [2 /*return*/, cacheFilehandler];
5428
- }
5429
- });
5430
- });
5431
- },
5432
- /**
5433
- * Scrapes the docx file and returns the knowledge pieces or `null` if it can't scrape it
5434
- */
5435
- scrape: function (source, options) {
5436
- return __awaiter(this, void 0, void 0, function () {
5437
- var cacheFilehandler, markdownSource, knowledge;
5438
- return __generator(this, function (_a) {
5439
- switch (_a.label) {
5440
- case 0: return [4 /*yield*/, documentScraper.$convert(source, options)];
5441
- case 1:
5442
- cacheFilehandler = _a.sent();
5443
- markdownSource = {
5444
- source: source.source,
5445
- filename: cacheFilehandler.filename,
5446
- url: null,
5447
- mimeType: 'text/markdown',
5448
- asText: function () {
5449
- return __awaiter(this, void 0, void 0, function () {
5450
- return __generator(this, function (_a) {
5451
- switch (_a.label) {
5452
- case 0: return [4 /*yield*/, readFile(cacheFilehandler.filename, 'utf-8')];
5453
- case 1:
5454
- // Note: [0] In $convert we check that the file exists
5455
- return [2 /*return*/, _a.sent()];
5456
- }
5457
- });
5458
- });
5459
- },
5460
- asJson: function () {
5461
- throw new UnexpectedError('Did not expect that `markdownScraper` would need to get the content `asJson`');
5462
- },
5463
- asBlob: function () {
5464
- throw new UnexpectedError('Did not expect that `markdownScraper` would need to get the content `asBlob`');
5465
- },
5466
- };
5467
- knowledge = markdownScraper.scrape(markdownSource, options);
5468
- return [4 /*yield*/, cacheFilehandler.destroy()];
5469
- case 2:
5470
- _a.sent();
5471
- return [2 /*return*/, knowledge];
5472
- }
5473
- });
5474
- });
5475
- },
5476
- } /* TODO: [🦷] as const */;
4933
+ var KnowledgeScrapeError = /** @class */ (function (_super) {
4934
+ __extends(KnowledgeScrapeError, _super);
4935
+ function KnowledgeScrapeError(message) {
4936
+ var _this = _super.call(this, message) || this;
4937
+ _this.name = 'KnowledgeScrapeError';
4938
+ Object.setPrototypeOf(_this, KnowledgeScrapeError.prototype);
4939
+ return _this;
4940
+ }
4941
+ return KnowledgeScrapeError;
4942
+ }(Error));
4943
+
5477
4944
  /**
5478
- * TODO: [👣] Converted documents can act as cached items - there is no need to run conversion each time
5479
- * TODO: [🦖] Make some system for putting scrapers to separete packages
5480
- * TODO: [🪂] Do it in parallel 11:11
5481
- * TODO: [🦷] Ideally use `as const satisfies Converter & Scraper` BUT this combination throws errors
5482
- * Note: No need to aggregate usage here, it is done by intercepting the llmTools
4945
+ * @@@
4946
+ *
4947
+ * Note: `$` is used to indicate that this function is not a pure function - it access global scope
4948
+ *
4949
+ * @private internal function of `$Register`
5483
4950
  */
4951
+ function $getGlobalScope() {
4952
+ return Function('return this')();
4953
+ }
5484
4954
 
5485
4955
  /**
5486
- * Scraper for .docx files
4956
+ * @@@
5487
4957
  *
5488
- * @see `documentationUrl` for more details
5489
- * @public exported from `@promptbook/core`
4958
+ * @param text @@@
4959
+ * @returns @@@
4960
+ * @example 'HELLO_WORLD'
4961
+ * @example 'I_LOVE_PROMPTBOOK'
4962
+ * @public exported from `@promptbook/utils`
5490
4963
  */
5491
- var legacyDocumentScraper = {
5492
- /**
5493
- * Mime types that this scraper can handle
5494
- */
5495
- mimeTypes: ['application/msword', 'text/rtf'],
5496
- /**
5497
- * Link to documentation
5498
- */
5499
- documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
5500
- /**
5501
- * Convert the `.doc` or `.rtf` to `.doc` file and returns intermediate source
5502
- *
5503
- * Note: `$` is used to indicate that this function is not a pure function - it leaves files on the disk and you are responsible for cleaning them by calling `destroy` method of returned object
5504
- */
5505
- $convert: function (source, options) {
5506
- return __awaiter(this, void 0, void 0, function () {
5507
- var _a, externalProgramsPaths, rootDirname, _b, cacheDirname, _c, isCacheCleaned, _d, isVerbose, extension, cacheFilehandler, documentSourceOutdirPathForLibreOffice_1, command_1, files_1, file;
5508
- return __generator(this, function (_e) {
5509
- switch (_e.label) {
5510
- case 0:
5511
- _a = options.externalProgramsPaths, externalProgramsPaths = _a === void 0 ? {} : _a, rootDirname = options.rootDirname, _b = options.cacheDirname, cacheDirname = _b === void 0 ? SCRAPE_CACHE_DIRNAME : _b, _c = options.isCacheCleaned, isCacheCleaned = _c === void 0 ? false : _c, _d = options.isVerbose, isVerbose = _d === void 0 ? IS_VERBOSE : _d;
5512
- if (!$isRunningInNode()) {
5513
- throw new KnowledgeScrapeError('Scraping .doc files is only supported in Node environment');
5514
- }
5515
- if (externalProgramsPaths.libreOfficePath === undefined) {
5516
- throw new MissingToolsError('LibreOffice is required for scraping .doc and .rtf files');
5517
- }
5518
- if (source.filename === null) {
5519
- // TODO: [🧠] Maybe save file as temporary
5520
- throw new KnowledgeScrapeError('When parsing .doc or .rtf file, it must be real file in the file system');
5521
- }
5522
- extension = getFileExtension(source.filename);
5523
- return [4 /*yield*/, getScraperIntermediateSource(source, {
5524
- rootDirname: rootDirname,
5525
- cacheDirname: cacheDirname,
5526
- isCacheCleaned: isCacheCleaned,
5527
- extension: 'docx',
5528
- isVerbose: isVerbose,
5529
- })];
5530
- case 1:
5531
- cacheFilehandler = _e.sent();
5532
- if (isVerbose) {
5533
- console.info("documentScraper: Converting .".concat(extension, " -> .docx"));
5534
- }
5535
- return [4 /*yield*/, $isFileExisting(cacheFilehandler.filename)];
5536
- case 2:
5537
- if (!!(_e.sent())) return [3 /*break*/, 8];
5538
- documentSourceOutdirPathForLibreOffice_1 = join(dirname(cacheFilehandler.filename), 'libreoffice')
5539
- .split('\\')
5540
- .join('/');
5541
- command_1 = "\"".concat(externalProgramsPaths.libreOfficePath, "\" --headless --convert-to docx \"").concat(source.filename, "\" --outdir \"").concat(documentSourceOutdirPathForLibreOffice_1, "\"");
5542
- // TODO: !!!!!! [🕊] Make execCommand standard (?node-)util of the promptbook - this should trigger build polution error
5543
- return [4 /*yield*/, $execCommand(command_1)];
5544
- case 3:
5545
- // TODO: !!!!!! [🕊] Make execCommand standard (?node-)util of the promptbook - this should trigger build polution error
5546
- _e.sent();
5547
- return [4 /*yield*/, readdir(documentSourceOutdirPathForLibreOffice_1)];
5548
- case 4:
5549
- files_1 = _e.sent();
5550
- if (files_1.length !== 1) {
5551
- throw new UnexpectedError(spaceTrim(function (block) { return "\n Expected exactly 1 file in the LibreOffice output directory, got ".concat(files_1.length, "\n\n The temporary folder:\n ").concat(block(documentSourceOutdirPathForLibreOffice_1), "\n\n Command:\n > ").concat(block(command_1), "\n "); }));
5552
- }
5553
- file = files_1[0];
5554
- return [4 /*yield*/, rename(join(documentSourceOutdirPathForLibreOffice_1, file), cacheFilehandler.filename)];
5555
- case 5:
5556
- _e.sent();
5557
- return [4 /*yield*/, rmdir(documentSourceOutdirPathForLibreOffice_1)];
5558
- case 6:
5559
- _e.sent();
5560
- return [4 /*yield*/, $isFileExisting(cacheFilehandler.filename)];
5561
- case 7:
5562
- if (!(_e.sent())) {
5563
- throw new UnexpectedError(spaceTrim(function (block) { return "\n File that was supposed to be created by LibreOffice does not exist for unknown reason\n\n Expected file:\n ".concat(block(cacheFilehandler.filename), "\n\n The temporary folder:\n ").concat(block(documentSourceOutdirPathForLibreOffice_1), "\n\n Command:\n > ").concat(block(command_1), "\n\n "); }));
5564
- }
5565
- _e.label = 8;
5566
- case 8: return [2 /*return*/, cacheFilehandler];
5567
- }
5568
- });
5569
- });
5570
- },
5571
- /**
5572
- * Scrapes the `.doc` or `.rtf` file and returns the knowledge pieces or `null` if it can't scrape it
5573
- */
5574
- scrape: function (source, options) {
5575
- return __awaiter(this, void 0, void 0, function () {
5576
- var cacheFilehandler, markdownSource, knowledge;
5577
- return __generator(this, function (_a) {
5578
- switch (_a.label) {
5579
- case 0: return [4 /*yield*/, legacyDocumentScraper.$convert(source, options)];
5580
- case 1:
5581
- cacheFilehandler = _a.sent();
5582
- markdownSource = {
5583
- source: source.source,
5584
- filename: cacheFilehandler.filename,
5585
- url: null,
5586
- mimeType: 'text/markdown',
5587
- asText: function () {
5588
- throw new UnexpectedError('Did not expect that `documentScraper` would need to get the content `asText`');
5589
- },
5590
- asJson: function () {
5591
- throw new UnexpectedError('Did not expect that `documentScraper` would need to get the content `asJson`');
5592
- },
5593
- asBlob: function () {
5594
- throw new UnexpectedError('Did not expect that `documentScraper` would need to get the content `asBlob`');
5595
- },
5596
- };
5597
- knowledge = documentScraper.scrape(markdownSource, options);
5598
- return [4 /*yield*/, cacheFilehandler.destroy()];
5599
- case 2:
5600
- _a.sent();
5601
- return [2 /*return*/, knowledge];
5602
- }
5603
- });
5604
- });
5605
- },
5606
- } /* TODO: [🦷] as const */;
4964
+ function normalizeTo_SCREAMING_CASE(text) {
4965
+ var e_1, _a;
4966
+ var charType;
4967
+ var lastCharType = 'OTHER';
4968
+ var normalizedName = '';
4969
+ try {
4970
+ for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
4971
+ var char = text_1_1.value;
4972
+ var normalizedChar = void 0;
4973
+ if (/^[a-z]$/.test(char)) {
4974
+ charType = 'LOWERCASE';
4975
+ normalizedChar = char.toUpperCase();
4976
+ }
4977
+ else if (/^[A-Z]$/.test(char)) {
4978
+ charType = 'UPPERCASE';
4979
+ normalizedChar = char;
4980
+ }
4981
+ else if (/^[0-9]$/.test(char)) {
4982
+ charType = 'NUMBER';
4983
+ normalizedChar = char;
4984
+ }
4985
+ else {
4986
+ charType = 'OTHER';
4987
+ normalizedChar = '_';
4988
+ }
4989
+ if (charType !== lastCharType &&
4990
+ !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
4991
+ !(lastCharType === 'NUMBER') &&
4992
+ !(charType === 'NUMBER')) {
4993
+ normalizedName += '_';
4994
+ }
4995
+ normalizedName += normalizedChar;
4996
+ lastCharType = charType;
4997
+ }
4998
+ }
4999
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
5000
+ finally {
5001
+ try {
5002
+ if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
5003
+ }
5004
+ finally { if (e_1) throw e_1.error; }
5005
+ }
5006
+ normalizedName = normalizedName.replace(/_+/g, '_');
5007
+ normalizedName = normalizedName.replace(/_?\/_?/g, '/');
5008
+ normalizedName = normalizedName.replace(/^_/, '');
5009
+ normalizedName = normalizedName.replace(/_$/, '');
5010
+ return normalizedName;
5011
+ }
5607
5012
  /**
5608
- * TODO: [👣] Converted documents can act as cached items - there is no need to run conversion each time
5609
- * TODO: [🦖] Make some system for putting scrapers to separete packages
5610
- * TODO: [🪂] Do it in parallel 11:11
5611
- * TODO: [🦷] Ideally use `as const satisfies Converter & Scraper` BUT this combination throws errors
5612
- * Note: No need to aggregate usage here, it is done by intercepting the llmTools
5013
+ * TODO: Tests
5014
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'Moje tabule' })).toEqual('/VtG7sR9rRJqwNEdM2/Moje tabule');
5015
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'ěščřžžýáíúů' })).toEqual('/VtG7sR9rRJqwNEdM2/escrzyaieuu');
5016
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj');
5017
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj_ahojAhoj ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj-ahoj-ahoj-ahoj');
5018
+ * TODO: [🌺] Use some intermediate util splitWords
5613
5019
  */
5614
5020
 
5615
5021
  /**
5616
- * Scraper for .docx files
5022
+ * @@@
5617
5023
  *
5618
- * @see `documentationUrl` for more details
5619
- * @public exported from `@promptbook/core`
5024
+ * @param text @@@
5025
+ * @returns @@@
5026
+ * @example 'hello_world'
5027
+ * @example 'i_love_promptbook'
5028
+ * @public exported from `@promptbook/utils`
5620
5029
  */
5621
- var pdfScraper = {
5622
- /**
5623
- * Mime types that this scraper can handle
5624
- */
5625
- mimeTypes: ['application/pdf'],
5626
- /**
5627
- * Link to documentation
5628
- */
5629
- documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
5630
- /**
5631
- * Converts the `.pdf` file to `.md` file and returns intermediate source
5632
- */
5633
- $convert: function (source, options) {
5634
- return __awaiter(this, void 0, void 0, function () {
5635
- return __generator(this, function (_a) {
5636
- TODO_USE(source);
5637
- TODO_USE(options);
5638
- throw new NotYetImplementedError('PDF conversion not yet implemented');
5639
- });
5640
- });
5641
- },
5642
- /**
5643
- * Scrapes the `.pdf` file and returns the knowledge pieces or `null` if it can't scrape it
5644
- */
5645
- scrape: function (source, options) {
5646
- return __awaiter(this, void 0, void 0, function () {
5647
- return __generator(this, function (_a) {
5648
- TODO_USE(source);
5649
- TODO_USE(options);
5650
- /*
5651
- const {
5652
- externalProgramsPaths = {},
5653
- cacheDirname = SCRAPE_CACHE_DIRNAME,
5654
- isCacheCleaned = false,
5655
- isVerbose = IS_VERBOSE,
5656
- } = options;
5657
- */
5658
- throw new NotYetImplementedError('PDF scraping not yet implemented');
5659
- });
5660
- });
5661
- },
5662
- } /* TODO: [🦷] as const */;
5030
+ function normalizeTo_snake_case(text) {
5031
+ return normalizeTo_SCREAMING_CASE(text).toLowerCase();
5032
+ }
5033
+
5663
5034
  /**
5664
- * TODO: [👣] Converted documents can act as cached items - there is no need to run conversion each time
5665
- * TODO: [🦖] Make some system for putting scrapers to separete packages
5666
- * TODO: [🪂] Do it in parallel 11:11
5667
- * TODO: [🦷] Ideally use `as const satisfies Converter & Scraper` BUT this combination throws errors
5668
- * Note: No need to aggregate usage here, it is done by intercepting the llmTools
5035
+ * Register is @@@
5036
+ *
5037
+ * Note: `$` is used to indicate that this function is not a pure function - it accesses and adds variables in global scope.
5038
+ *
5039
+ * @private internal utility, exported are only signleton instances of this class
5669
5040
  */
5041
+ var $Register = /** @class */ (function () {
5042
+ function $Register(registerName) {
5043
+ this.registerName = registerName;
5044
+ var storageName = "_promptbook_".concat(normalizeTo_snake_case(registerName));
5045
+ var globalScope = $getGlobalScope();
5046
+ if (globalScope[storageName] === undefined) {
5047
+ globalScope[storageName] = [];
5048
+ }
5049
+ else if (!Array.isArray(globalScope[storageName])) {
5050
+ throw new UnexpectedError("Expected (global) ".concat(storageName, " to be an array, but got ").concat(typeof globalScope[storageName]));
5051
+ }
5052
+ this.storage = globalScope[storageName];
5053
+ }
5054
+ $Register.prototype.list = function () {
5055
+ // <- TODO: ReadonlyDeep<Array<TRegistered>>
5056
+ return this.storage;
5057
+ };
5058
+ $Register.prototype.register = function (registered) {
5059
+ var packageName = registered.packageName, className = registered.className;
5060
+ var existingRegistrationIndex = this.storage.findIndex(function (item) { return item.packageName === packageName && item.className === className; });
5061
+ var existingRegistration = this.storage[existingRegistrationIndex];
5062
+ if (!existingRegistration) {
5063
+ this.storage.push(registered);
5064
+ }
5065
+ else {
5066
+ this.storage[existingRegistrationIndex] = registered;
5067
+ }
5068
+ return {
5069
+ registerName: this.registerName,
5070
+ packageName: packageName,
5071
+ className: className,
5072
+ get isDestroyed() {
5073
+ return false;
5074
+ },
5075
+ destroy: function () {
5076
+ throw new NotYetImplementedError("Registration to ".concat(this.registerName, " is permanent in this version of Promptbook"));
5077
+ },
5078
+ };
5079
+ };
5080
+ return $Register;
5081
+ }());
5670
5082
 
5671
5083
  /**
5672
- * A converter instance that uses showdown and highlight extensions
5084
+ * @@@
5673
5085
  *
5674
- * @type {Converter}
5675
- * @private for markdown and html knowledge scrapers
5086
+ * Note: `$` is used to indicate that this interacts with the global scope
5087
+ * @singleton Only one instance of each register is created per build, but thare can be more @@@
5088
+ * @public exported from `@promptbook/core`
5676
5089
  */
5677
- var markdownConverter = new Converter({
5678
- flavor: 'github', // <- TODO: !!!!!! Explicitly specify the flavor of promptbook markdown
5679
- /*
5680
- > import showdownHighlight from 'showdown-highlight';
5681
- > extensions: [
5682
- > showdownHighlight({
5683
- > // Whether to add the classes to the <pre> tag, default is false
5684
- > pre: true,
5685
- > // Whether to use hljs' auto language detection, default is true
5686
- > auto_detection: true,
5687
- > }),
5688
- > ],
5689
- */
5690
- });
5090
+ var $scrapersMetadataRegister = new $Register('scrapers_metadata');
5691
5091
  /**
5692
- * TODO: !!!!!! Figure out better name not to confuse with `Converter`
5693
- * TODO: !!!!!! Lazy-make converter
5092
+ * TODO: [®] DRY Register logic
5694
5093
  */
5695
5094
 
5696
5095
  /**
5697
- * Scraper for .docx files
5096
+ * @@@
5698
5097
  *
5699
- * @see `documentationUrl` for more details
5098
+ * Note: `$` is used to indicate that this interacts with the global scope
5099
+ * @singleton Only one instance of each register is created per build, but thare can be more @@@
5700
5100
  * @public exported from `@promptbook/core`
5701
5101
  */
5702
- var websiteScraper = {
5703
- /**
5704
- * Mime types that this scraper can handle
5705
- */
5706
- mimeTypes: ['text/html'],
5707
- /**
5708
- * Link to documentation
5709
- */
5710
- documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
5102
+ var $scrapersRegister = new $Register('scraper_constructors');
5103
+ /**
5104
+ * TODO: [®] DRY Register logic
5105
+ */
5106
+
5107
+ // TODO: !!!!!! Maybe delete this function
5108
+ /**
5109
+ * Creates a message with all registered scrapers
5110
+ *
5111
+ * Note: This function is used to create a (error) message when there is no scraper for particular mime type
5112
+ *
5113
+ * @private internal function of `createScrapersFromConfiguration` and `createScrapersFromEnv`
5114
+ */
5115
+ function $registeredScrapersMessage() {
5116
+ var e_1, _a, e_2, _b;
5711
5117
  /**
5712
- * Convert the website to `.md` file and returns intermediate source
5713
- *
5714
- * Note: `$` is used to indicate that this function is not a pure function - it leaves files on the disk and you are responsible for cleaning them by calling `destroy` method of returned object
5118
+ * Mixes registered scrapers from $scrapersMetadataRegister and $scrapersRegister
5715
5119
  */
5716
- $convert: function (source, options) {
5717
- return __awaiter(this, void 0, void 0, function () {
5718
- var
5719
- // TODO: [🧠] Maybe in node use headless browser not just JSDOM
5720
- // externalProgramsPaths = {},
5721
- rootDirname, _a, cacheDirname, _b, isCacheCleaned, _c, isVerbose, jsdom, _d, reader, article, html, i, cacheFilehandler, markdown;
5722
- return __generator(this, function (_e) {
5723
- switch (_e.label) {
5724
- case 0:
5725
- rootDirname = options.rootDirname, _a = options.cacheDirname, cacheDirname = _a === void 0 ? SCRAPE_CACHE_DIRNAME : _a, _b = options.isCacheCleaned, isCacheCleaned = _b === void 0 ? false : _b, _c = options.isVerbose, isVerbose = _c === void 0 ? IS_VERBOSE : _c;
5726
- // TODO: !!!!!! Does this work in browser? Make it work.
5727
- if (source.url === null) {
5728
- throw new KnowledgeScrapeError('Website scraper requires URL');
5729
- }
5730
- _d = JSDOM.bind;
5731
- return [4 /*yield*/, source.asText()];
5732
- case 1:
5733
- jsdom = new (_d.apply(JSDOM, [void 0, _e.sent(), {
5734
- url: source.url,
5735
- }]))();
5736
- reader = new Readability(jsdom.window.document);
5737
- article = reader.parse();
5738
- console.log(article);
5739
- return [4 /*yield*/, forTime(10000)];
5740
- case 2:
5741
- _e.sent();
5742
- html = (article === null || article === void 0 ? void 0 : article.content) || (article === null || article === void 0 ? void 0 : article.textContent) || jsdom.window.document.body.innerHTML;
5743
- // Note: Unwrap html such as it is convertable by `markdownConverter`
5744
- for (i = 0; i < 2; i++) {
5745
- html = html.replace(/<div\s*(?:id="readability-page-\d+"\s+class="page")?>(.*)<\/div>/is, '$1');
5746
- }
5747
- if (html.includes('<div')) {
5748
- html = (article === null || article === void 0 ? void 0 : article.textContent) || '';
5749
- }
5750
- return [4 /*yield*/, getScraperIntermediateSource(source, {
5751
- rootDirname: rootDirname,
5752
- cacheDirname: cacheDirname,
5753
- isCacheCleaned: isCacheCleaned,
5754
- extension: 'html',
5755
- isVerbose: isVerbose,
5756
- })];
5757
- case 3:
5758
- cacheFilehandler = _e.sent();
5759
- return [4 /*yield*/, writeFile(cacheFilehandler.filename, html, 'utf-8')];
5760
- case 4:
5761
- _e.sent();
5762
- markdown = markdownConverter.makeMarkdown(html, jsdom.window.document);
5763
- return [2 /*return*/, __assign(__assign({}, cacheFilehandler), { markdown: markdown })];
5764
- }
5765
- });
5120
+ var all = [];
5121
+ var _loop_1 = function (packageName, className) {
5122
+ if (all.some(function (item) { return item.packageName === packageName && item.className === className; })) {
5123
+ return "continue";
5124
+ }
5125
+ all.push({ packageName: packageName, className: className });
5126
+ };
5127
+ try {
5128
+ for (var _c = __values($scrapersMetadataRegister.list()), _d = _c.next(); !_d.done; _d = _c.next()) {
5129
+ var _e = _d.value, packageName = _e.packageName, className = _e.className;
5130
+ _loop_1(packageName, className);
5131
+ }
5132
+ }
5133
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
5134
+ finally {
5135
+ try {
5136
+ if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
5137
+ }
5138
+ finally { if (e_1) throw e_1.error; }
5139
+ }
5140
+ var _loop_2 = function (packageName, className) {
5141
+ if (all.some(function (item) { return item.packageName === packageName && item.className === className; })) {
5142
+ return "continue";
5143
+ }
5144
+ all.push({ packageName: packageName, className: className });
5145
+ };
5146
+ try {
5147
+ for (var _f = __values($scrapersRegister.list()), _g = _f.next(); !_g.done; _g = _f.next()) {
5148
+ var _h = _g.value, packageName = _h.packageName, className = _h.className;
5149
+ _loop_2(packageName, className);
5150
+ }
5151
+ }
5152
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
5153
+ finally {
5154
+ try {
5155
+ if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
5156
+ }
5157
+ finally { if (e_2) throw e_2.error; }
5158
+ }
5159
+ var metadata = all.map(function (metadata) {
5160
+ var isMetadataAviailable = $scrapersMetadataRegister
5161
+ .list()
5162
+ .find(function (_a) {
5163
+ var packageName = _a.packageName, className = _a.className;
5164
+ return metadata.packageName === packageName && metadata.className === className;
5766
5165
  });
5767
- },
5768
- /**
5769
- * Scrapes the website and returns the knowledge pieces or `null` if it can't scrape it
5770
- */
5771
- scrape: function (source, options) {
5772
- return __awaiter(this, void 0, void 0, function () {
5773
- var cacheFilehandler, markdownSource, knowledge;
5774
- return __generator(this, function (_a) {
5775
- switch (_a.label) {
5776
- case 0: return [4 /*yield*/, websiteScraper.$convert(source, options)];
5777
- case 1:
5778
- cacheFilehandler = _a.sent();
5779
- markdownSource = {
5780
- source: source.source,
5781
- filename: cacheFilehandler.filename,
5782
- url: null,
5783
- mimeType: 'text/markdown',
5784
- asText: function () {
5785
- return cacheFilehandler.markdown;
5786
- },
5787
- asJson: function () {
5788
- throw new UnexpectedError('Did not expect that `markdownScraper` would need to get the content `asJson`');
5789
- },
5790
- asBlob: function () {
5791
- throw new UnexpectedError('Did not expect that `markdownScraper` would need to get the content `asBlob`');
5792
- },
5793
- };
5794
- knowledge = markdownScraper.scrape(markdownSource, options);
5795
- return [4 /*yield*/, cacheFilehandler.destroy()];
5796
- case 2:
5797
- _a.sent();
5798
- return [2 /*return*/, knowledge];
5799
- }
5800
- });
5166
+ var isInstalled = $scrapersRegister
5167
+ .list()
5168
+ .find(function (_a) {
5169
+ var packageName = _a.packageName, className = _a.className;
5170
+ return metadata.packageName === packageName && metadata.className === className;
5801
5171
  });
5802
- },
5803
- } /* TODO: [🦷] as const */;
5172
+ return __assign(__assign({}, metadata), { isMetadataAviailable: isMetadataAviailable, isInstalled: isInstalled });
5173
+ });
5174
+ if (metadata.length === 0) {
5175
+ return "No scrapers are available";
5176
+ }
5177
+ return spaceTrim(function (block) { return "\n Available scrapers are:\n ".concat(block(metadata
5178
+ .map(function (_a, i) {
5179
+ var packageName = _a.packageName, className = _a.className, isMetadataAviailable = _a.isMetadataAviailable, isInstalled = _a.isInstalled;
5180
+ var more;
5181
+ if (just(false)) {
5182
+ more = '';
5183
+ }
5184
+ else if (!isMetadataAviailable && !isInstalled) {
5185
+ // TODO: [�][�] Maybe do allow to do auto-install if package not registered and not found
5186
+ more = "(not installed and no metadata, looks like a unexpected behavior)";
5187
+ }
5188
+ else if (isMetadataAviailable && !isInstalled) {
5189
+ // TODO: [�][�]
5190
+ more = "(not installed)";
5191
+ }
5192
+ else if (!isMetadataAviailable && isInstalled) {
5193
+ more = "(no metadata, looks like a unexpected behavior)";
5194
+ }
5195
+ else if (isMetadataAviailable && isInstalled) {
5196
+ more = "(installed)";
5197
+ }
5198
+ else {
5199
+ more = "(unknown state, looks like a unexpected behavior)";
5200
+ }
5201
+ return "".concat(i + 1, ") `").concat(className, "` from `").concat(packageName, "` ").concat(more);
5202
+ })
5203
+ .join('\n')), "\n "); });
5204
+ }
5804
5205
  /**
5805
- * TODO: !!!!!! Put into separate package
5806
- * TODO: [👣] Scraped website in .md can act as cache item - there is no need to run conversion each time
5807
- * TODO: [🦖] Make some system for putting scrapers to separete packages
5808
- * TODO: [🪂] Do it in parallel 11:11
5809
- * TODO: [🦷] Ideally use `as const satisfies Converter & Scraper` BUT this combination throws errors
5810
- * Note: No need to aggregate usage here, it is done by intercepting the llmTools
5206
+ * TODO: [®] DRY Register logic
5811
5207
  */
5812
5208
 
5813
- // TODO: [🦖] !!!!!! Pass scrapers as dependency,
5814
5209
  /**
5815
5210
  * @@@
5816
5211
  *
5817
- * @private because this will be replaced by a system of one scraper per package [🦖]
5818
- * TODO: [🦖] System for scrapers NOT public exported from `@promptbook/core`
5212
+ * @param text @@@
5213
+ * @returns @@@
5214
+ * @example 'hello-world'
5215
+ * @example 'i-love-promptbook'
5216
+ * @public exported from `@promptbook/utils`
5819
5217
  */
5820
- var SCRAPERS = [
5821
- markdownScraper,
5822
- documentScraper,
5823
- legacyDocumentScraper,
5824
- pdfScraper,
5825
- websiteScraper,
5826
- // <- Note: [♓️] This is the order of the scrapers for knowledge, BUT consider some better (more explicit) way to do this
5827
- ];
5218
+ function normalizeToKebabCase(text) {
5219
+ var e_1, _a;
5220
+ text = removeDiacritics(text);
5221
+ var charType;
5222
+ var lastCharType = 'OTHER';
5223
+ var normalizedName = '';
5224
+ try {
5225
+ for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
5226
+ var char = text_1_1.value;
5227
+ var normalizedChar = void 0;
5228
+ if (/^[a-z]$/.test(char)) {
5229
+ charType = 'LOWERCASE';
5230
+ normalizedChar = char;
5231
+ }
5232
+ else if (/^[A-Z]$/.test(char)) {
5233
+ charType = 'UPPERCASE';
5234
+ normalizedChar = char.toLowerCase();
5235
+ }
5236
+ else if (/^[0-9]$/.test(char)) {
5237
+ charType = 'NUMBER';
5238
+ normalizedChar = char;
5239
+ }
5240
+ else {
5241
+ charType = 'OTHER';
5242
+ normalizedChar = '-';
5243
+ }
5244
+ if (charType !== lastCharType &&
5245
+ !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
5246
+ !(lastCharType === 'NUMBER') &&
5247
+ !(charType === 'NUMBER')) {
5248
+ normalizedName += '-';
5249
+ }
5250
+ normalizedName += normalizedChar;
5251
+ lastCharType = charType;
5252
+ }
5253
+ }
5254
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
5255
+ finally {
5256
+ try {
5257
+ if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
5258
+ }
5259
+ finally { if (e_1) throw e_1.error; }
5260
+ }
5261
+ normalizedName = normalizedName.split(/-+/g).join('-');
5262
+ normalizedName = normalizedName.split(/-?\/-?/g).join('/');
5263
+ normalizedName = normalizedName.replace(/^-/, '');
5264
+ normalizedName = normalizedName.replace(/-$/, '');
5265
+ return normalizedName;
5266
+ }
5828
5267
 
5829
5268
  /**
5830
5269
  * Creates unique name for the source
@@ -5857,15 +5296,89 @@ function extensionToMimeType(value) {
5857
5296
  return lookup(value) || 'application/octet-stream';
5858
5297
  }
5859
5298
 
5299
+ /**
5300
+ * Get the file extension from a file name
5301
+ *
5302
+ * @private within the repository
5303
+ */
5304
+ function getFileExtension(value) {
5305
+ var match = value.match(/\.([0-9a-z]+)(?:[?#]|$)/i);
5306
+ return match ? match[1].toLowerCase() : null;
5307
+ }
5308
+
5309
+ /**
5310
+ * Checks if the file exists
5311
+ *
5312
+ * @private within the repository
5313
+ */
5314
+ function isFileExisting(filename, fs) {
5315
+ return __awaiter(this, void 0, void 0, function () {
5316
+ var isReadAccessAllowed, isFile;
5317
+ return __generator(this, function (_a) {
5318
+ switch (_a.label) {
5319
+ case 0: return [4 /*yield*/, fs
5320
+ .access(filename, fs.constants.R_OK)
5321
+ .then(function () { return true; })
5322
+ .catch(function () { return false; })];
5323
+ case 1:
5324
+ isReadAccessAllowed = _a.sent();
5325
+ if (!isReadAccessAllowed) {
5326
+ return [2 /*return*/, false];
5327
+ }
5328
+ return [4 /*yield*/, fs
5329
+ .stat(filename)
5330
+ .then(function (fileStat) { return fileStat.isFile(); })
5331
+ .catch(function () { return false; })];
5332
+ case 2:
5333
+ isFile = _a.sent();
5334
+ return [2 /*return*/, isFile];
5335
+ }
5336
+ });
5337
+ });
5338
+ }
5339
+ /**
5340
+ * Note: Not [~🟢~] because it is not directly dependent on `fs
5341
+ * TODO: [🐠] This can be a validator - with variants that return true/false and variants that throw errors with meaningless messages
5342
+ * TODO: [🖇] What about symlinks?
5343
+ */
5344
+
5345
+ /**
5346
+ * Tests if given string is valid URL.
5347
+ *
5348
+ * Note: This does not check if the file exists only if the path is valid
5349
+ * @public exported from `@promptbook/utils`
5350
+ */
5351
+ function isValidFilePath(filename) {
5352
+ if (typeof filename !== 'string') {
5353
+ return false;
5354
+ }
5355
+ var filenameSlashes = filename.split('\\').join('/');
5356
+ // Absolute Unix path: /hello.txt
5357
+ if (/^(\/)/i.test(filenameSlashes)) {
5358
+ return true;
5359
+ }
5360
+ // Absolute Windows path: /hello.txt
5361
+ if (/^([A-Z]{1,2}:\/?)\//i.test(filenameSlashes)) {
5362
+ return true;
5363
+ }
5364
+ // Relative path: ./hello.txt
5365
+ if (/^(\.\.?\/)+/i.test(filenameSlashes)) {
5366
+ return true;
5367
+ }
5368
+ return false;
5369
+ }
5370
+
5860
5371
  /**
5861
5372
  * @@@
5862
5373
  *
5863
5374
  * @private for scraper utilities
5864
5375
  */
5865
- function makeKnowledgeSourceHandler(knowledgeSource, options) {
5376
+ function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
5866
5377
  var _a;
5867
5378
  return __awaiter(this, void 0, void 0, function () {
5868
- var sourceContent, name, _b, _c, rootDirname, _d, isVerbose, url, response_1, mimeType, filename_1, fileExtension, mimeType_1;
5379
+ var sourceContent, name, _b, _c, rootDirname, _d,
5380
+ // <- TODO: process.cwd() if running in Node.js
5381
+ isVerbose, url, response_1, mimeType, filename_1, fileExtension, mimeType_1;
5869
5382
  return __generator(this, function (_e) {
5870
5383
  switch (_e.label) {
5871
5384
  case 0:
@@ -5929,8 +5442,9 @@ function makeKnowledgeSourceHandler(knowledgeSource, options) {
5929
5442
  }];
5930
5443
  case 2:
5931
5444
  if (!(isValidFilePath(sourceContent) || /\.[a-z]{1,10}$/i.exec(sourceContent))) return [3 /*break*/, 4];
5932
- if (!$isRunningInNode()) {
5933
- throw new EnvironmentMismatchError('Importing knowledge source file works only in Node.js environment');
5445
+ if (tools.fs === undefined) {
5446
+ throw new EnvironmentMismatchError('Can not import file knowledge without filesystem tools');
5447
+ // <- TODO: [🧠] What is the best error type here`
5934
5448
  }
5935
5449
  if (rootDirname === null) {
5936
5450
  throw new EnvironmentMismatchError('Can not import file knowledge in non-file pipeline');
@@ -5939,7 +5453,7 @@ function makeKnowledgeSourceHandler(knowledgeSource, options) {
5939
5453
  filename_1 = join(rootDirname, sourceContent).split('\\').join('/');
5940
5454
  fileExtension = getFileExtension(filename_1);
5941
5455
  mimeType_1 = extensionToMimeType(fileExtension || '');
5942
- return [4 /*yield*/, $isFileExisting(filename_1)];
5456
+ return [4 /*yield*/, isFileExisting(filename_1, tools.fs)];
5943
5457
  case 3:
5944
5458
  if (!(_e.sent())) {
5945
5459
  throw new NotFoundError(spaceTrim(function (block) { return "\n Can not make source handler for file which does not exist:\n\n File:\n ".concat(block(filename_1), "\n "); }));
@@ -5955,10 +5469,9 @@ function makeKnowledgeSourceHandler(knowledgeSource, options) {
5955
5469
  var content;
5956
5470
  return __generator(this, function (_a) {
5957
5471
  switch (_a.label) {
5958
- case 0: return [4 /*yield*/, readFile(filename_1)];
5472
+ case 0: return [4 /*yield*/, tools.fs.readFile(filename_1)];
5959
5473
  case 1:
5960
5474
  content = _a.sent();
5961
- // <- Note: Its OK to use sync in tooling for tests
5962
5475
  return [2 /*return*/, new Blob([
5963
5476
  content,
5964
5477
  // <- TODO: !!!!!! Maybe not working
@@ -5974,7 +5487,7 @@ function makeKnowledgeSourceHandler(knowledgeSource, options) {
5974
5487
  switch (_c.label) {
5975
5488
  case 0:
5976
5489
  _b = (_a = JSON).parse;
5977
- return [4 /*yield*/, readFile(filename_1, 'utf-8')];
5490
+ return [4 /*yield*/, tools.fs.readFile(filename_1, 'utf-8')];
5978
5491
  case 1: return [2 /*return*/, _b.apply(_a, [_c.sent()])];
5979
5492
  }
5980
5493
  });
@@ -5984,7 +5497,7 @@ function makeKnowledgeSourceHandler(knowledgeSource, options) {
5984
5497
  return __awaiter(this, void 0, void 0, function () {
5985
5498
  return __generator(this, function (_a) {
5986
5499
  switch (_a.label) {
5987
- case 0: return [4 /*yield*/, readFile(filename_1, 'utf-8')];
5500
+ case 0: return [4 /*yield*/, tools.fs.readFile(filename_1, 'utf-8')];
5988
5501
  case 1: return [2 /*return*/, _a.sent()];
5989
5502
  }
5990
5503
  });
@@ -6017,7 +5530,7 @@ function makeKnowledgeSourceHandler(knowledgeSource, options) {
6017
5530
  * @see https://github.com/webgptorg/promptbook/discussions/41
6018
5531
  * @public exported from `@promptbook/core`
6019
5532
  */
6020
- function prepareKnowledgePieces(knowledgeSources, options) {
5533
+ function prepareKnowledgePieces(knowledgeSources, tools, options) {
6021
5534
  return __awaiter(this, void 0, void 0, function () {
6022
5535
  var _a, maxParallelCount, rootDirname, _b, isVerbose, knowledgePreparedUnflatten, knowledgePrepared;
6023
5536
  var _this = this;
@@ -6027,55 +5540,53 @@ function prepareKnowledgePieces(knowledgeSources, options) {
6027
5540
  _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? MAX_PARALLEL_COUNT : _a, rootDirname = options.rootDirname, _b = options.isVerbose, isVerbose = _b === void 0 ? IS_VERBOSE : _b;
6028
5541
  knowledgePreparedUnflatten = new Array(knowledgeSources.length);
6029
5542
  return [4 /*yield*/, forEachAsync(knowledgeSources, { maxParallelCount: maxParallelCount }, function (knowledgeSource, index) { return __awaiter(_this, void 0, void 0, function () {
6030
- var partialPieces, sourceHandler, SCRAPERS_1, SCRAPERS_1_1, scraper, partialPiecesUnchecked, e_1_1, pieces;
6031
- var e_1, _a;
6032
- return __generator(this, function (_b) {
6033
- switch (_b.label) {
5543
+ var partialPieces, sourceHandler, _a, _b, scraper, partialPiecesUnchecked, e_1_1, pieces;
5544
+ var e_1, _c;
5545
+ return __generator(this, function (_d) {
5546
+ switch (_d.label) {
6034
5547
  case 0:
6035
5548
  partialPieces = null;
6036
- return [4 /*yield*/, makeKnowledgeSourceHandler(knowledgeSource, { rootDirname: rootDirname, isVerbose: isVerbose })];
5549
+ return [4 /*yield*/, makeKnowledgeSourceHandler(knowledgeSource, tools, { rootDirname: rootDirname, isVerbose: isVerbose })];
6037
5550
  case 1:
6038
- sourceHandler = _b.sent();
6039
- _b.label = 2;
5551
+ sourceHandler = _d.sent();
5552
+ _d.label = 2;
6040
5553
  case 2:
6041
- _b.trys.push([2, 7, 8, 9]);
6042
- SCRAPERS_1 = __values(SCRAPERS), SCRAPERS_1_1 = SCRAPERS_1.next();
6043
- _b.label = 3;
5554
+ _d.trys.push([2, 7, 8, 9]);
5555
+ _a = __values(arrayableToArray(tools.scrapers)), _b = _a.next();
5556
+ _d.label = 3;
6044
5557
  case 3:
6045
- if (!!SCRAPERS_1_1.done) return [3 /*break*/, 6];
6046
- scraper = SCRAPERS_1_1.value;
6047
- if (!scraper.mimeTypes.includes(sourceHandler.mimeType)
5558
+ if (!!_b.done) return [3 /*break*/, 6];
5559
+ scraper = _b.value;
5560
+ if (!scraper.metadata.mimeTypes.includes(sourceHandler.mimeType)
6048
5561
  // <- TODO: [🦔] Implement mime-type wildcards
6049
5562
  ) {
6050
5563
  return [3 /*break*/, 5];
6051
5564
  }
6052
- return [4 /*yield*/, scraper.scrape(sourceHandler, options)];
5565
+ return [4 /*yield*/, scraper.scrape(sourceHandler)];
6053
5566
  case 4:
6054
- partialPiecesUnchecked = _b.sent();
5567
+ partialPiecesUnchecked = _d.sent();
6055
5568
  if (partialPiecesUnchecked !== null) {
6056
5569
  partialPieces = partialPiecesUnchecked;
6057
5570
  return [3 /*break*/, 6];
6058
5571
  }
6059
- _b.label = 5;
5572
+ _d.label = 5;
6060
5573
  case 5:
6061
- SCRAPERS_1_1 = SCRAPERS_1.next();
5574
+ _b = _a.next();
6062
5575
  return [3 /*break*/, 3];
6063
5576
  case 6: return [3 /*break*/, 9];
6064
5577
  case 7:
6065
- e_1_1 = _b.sent();
5578
+ e_1_1 = _d.sent();
6066
5579
  e_1 = { error: e_1_1 };
6067
5580
  return [3 /*break*/, 9];
6068
5581
  case 8:
6069
5582
  try {
6070
- if (SCRAPERS_1_1 && !SCRAPERS_1_1.done && (_a = SCRAPERS_1.return)) _a.call(SCRAPERS_1);
5583
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
6071
5584
  }
6072
5585
  finally { if (e_1) throw e_1.error; }
6073
5586
  return [7 /*endfinally*/];
6074
5587
  case 9:
6075
5588
  if (partialPieces === null) {
6076
- throw new KnowledgeScrapeError(spaceTrim(function (block) { return "\n Cannot scrape knowledge from source: ".concat(knowledgeSource.sourceContent, "\n\n No scraper found for the mime type \"").concat(sourceHandler.mimeType, "\"\n\n Available scrapers:\n ").concat(block(SCRAPERS.flatMap(function (scraper) { return scraper.mimeTypes; })
6077
- .map(function (mimeType) { return "- ".concat(mimeType); })
6078
- .join('\n')), "\n\n\n "); }));
5589
+ throw new KnowledgeScrapeError(spaceTrim(function (block) { return "\n Cannot scrape knowledge from source: ".concat(knowledgeSource.sourceContent, "\n\n No scraper found for the mime type \"").concat(sourceHandler.mimeType, "\"\n\n ").concat(block($registeredScrapersMessage()), "\n\n\n "); }));
6079
5590
  }
6080
5591
  pieces = partialPieces.map(function (partialPiece) { return (__assign(__assign({}, partialPiece), { sources: [
6081
5592
  {
@@ -6083,196 +5594,41 @@ function prepareKnowledgePieces(knowledgeSources, options) {
6083
5594
  // line, column <- TODO: [☀]
6084
5595
  // <- TODO: [❎]
6085
5596
  },
6086
- ] })); });
6087
- knowledgePreparedUnflatten[index] = pieces;
6088
- return [2 /*return*/];
6089
- }
6090
- });
6091
- }); })];
6092
- case 1:
6093
- _c.sent();
6094
- knowledgePrepared = knowledgePreparedUnflatten.flat();
6095
- return [2 /*return*/, knowledgePrepared];
6096
- }
6097
- });
6098
- });
6099
- }
6100
- /*
6101
- TODO: [🧊] This is how it can look in future
6102
- > type PrepareKnowledgeKnowledge = {
6103
- > /**
6104
- > * Unprepared knowledge
6105
- > * /
6106
- > readonly knowledgeSources: Array<KnowledgeSourceJson>;
6107
- > };
6108
- >
6109
- > export async function prepareKnowledgePieces(
6110
- > knowledge: PrepareKnowledgeKnowledge,
6111
- > options: PrepareAndScrapeOptions,
6112
- > ):
6113
- */
6114
- /**
6115
- * TODO: [🧊] In future one preparation can take data from previous preparation and save tokens and time
6116
- * Put `knowledgePieces` into `PrepareKnowledgeOptions`
6117
- * TODO: [🪂] More than max things can run in parallel by acident [1,[2a,2b,_],[3a,3b,_]]
6118
- * TODO: [🧠][❎] Do here propper M:N mapping
6119
- * [x] One source can make multiple pieces
6120
- * [ ] One piece can have multiple sources
6121
- */
6122
-
6123
- /**
6124
- * Intercepts LLM tools and counts total usage of the tools
6125
- *
6126
- * @param llmTools LLM tools to be intercepted with usage counting
6127
- * @returns LLM tools with same functionality with added total cost counting
6128
- * @public exported from `@promptbook/core`
6129
- */
6130
- function countTotalUsage(llmTools) {
6131
- var _this = this;
6132
- var totalUsage = ZERO_USAGE;
6133
- var proxyTools = {
6134
- get title() {
6135
- // TODO: [🧠] Maybe put here some suffix
6136
- return llmTools.title;
6137
- },
6138
- get description() {
6139
- // TODO: [🧠] Maybe put here some suffix
6140
- return llmTools.description;
6141
- },
6142
- checkConfiguration: function () {
6143
- return __awaiter(this, void 0, void 0, function () {
6144
- return __generator(this, function (_a) {
6145
- return [2 /*return*/, /* not await */ llmTools.checkConfiguration()];
6146
- });
6147
- });
6148
- },
6149
- listModels: function () {
6150
- return /* not await */ llmTools.listModels();
6151
- },
6152
- getTotalUsage: function () {
6153
- // <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
6154
- return totalUsage;
6155
- },
6156
- };
6157
- if (llmTools.callChatModel !== undefined) {
6158
- proxyTools.callChatModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
6159
- var promptResult;
6160
- return __generator(this, function (_a) {
6161
- switch (_a.label) {
6162
- case 0: return [4 /*yield*/, llmTools.callChatModel(prompt)];
6163
- case 1:
6164
- promptResult = _a.sent();
6165
- totalUsage = addUsage(totalUsage, promptResult.usage);
6166
- return [2 /*return*/, promptResult];
6167
- }
6168
- });
6169
- }); };
6170
- }
6171
- if (llmTools.callCompletionModel !== undefined) {
6172
- proxyTools.callCompletionModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
6173
- var promptResult;
6174
- return __generator(this, function (_a) {
6175
- switch (_a.label) {
6176
- case 0: return [4 /*yield*/, llmTools.callCompletionModel(prompt)];
6177
- case 1:
6178
- promptResult = _a.sent();
6179
- totalUsage = addUsage(totalUsage, promptResult.usage);
6180
- return [2 /*return*/, promptResult];
6181
- }
6182
- });
6183
- }); };
6184
- }
6185
- if (llmTools.callEmbeddingModel !== undefined) {
6186
- proxyTools.callEmbeddingModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
6187
- var promptResult;
6188
- return __generator(this, function (_a) {
6189
- switch (_a.label) {
6190
- case 0: return [4 /*yield*/, llmTools.callEmbeddingModel(prompt)];
6191
- case 1:
6192
- promptResult = _a.sent();
6193
- totalUsage = addUsage(totalUsage, promptResult.usage);
6194
- return [2 /*return*/, promptResult];
6195
- }
6196
- });
6197
- }); };
6198
- }
6199
- // <- Note: [🤖]
6200
- return proxyTools;
6201
- }
6202
- /**
6203
- * TODO: [🧠][💸] Maybe make some common abstraction `interceptLlmTools` and use here (or use javascript Proxy?)
6204
- * TODO: [🧠] Is there some meaningfull way how to test this util
6205
- * TODO: [🧠][🌯] Maybe a way how to hide ability to `get totalUsage`
6206
- * > const [llmToolsWithUsage,getUsage] = countTotalUsage(llmTools);
6207
- * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
6208
- */
6209
-
6210
- /**
6211
- * Prepares the persona for the pipeline
6212
- *
6213
- * @see https://github.com/webgptorg/promptbook/discussions/22
6214
- * @public exported from `@promptbook/core`
6215
- */
6216
- function preparePersona(personaDescription, options) {
6217
- return __awaiter(this, void 0, void 0, function () {
6218
- var llmTools, _a, isVerbose, collection, preparePersonaExecutor, _b, availableModels, availableModelNames, result, outputParameters, modelRequirementsRaw, modelRequirements, modelName, systemMessage, temperature;
6219
- var _c;
6220
- return __generator(this, function (_d) {
6221
- switch (_d.label) {
6222
- case 0:
6223
- llmTools = options.llmTools, _a = options.isVerbose, isVerbose = _a === void 0 ? IS_VERBOSE : _a;
6224
- if (llmTools === undefined) {
6225
- throw new MissingToolsError('LLM tools are required for preparing persona');
6226
- }
6227
- collection = createCollectionFromJson.apply(void 0, __spreadArray([], __read(PipelineCollection), false));
6228
- _b = createPipelineExecutor;
6229
- _c = {};
6230
- return [4 /*yield*/, collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-persona.ptbk.md')];
6231
- case 1:
6232
- preparePersonaExecutor = _b.apply(void 0, [(_c.pipeline = _d.sent(),
6233
- _c.tools = {
6234
- llm: llmTools,
6235
- },
6236
- _c)]);
6237
- return [4 /*yield*/, llmTools.listModels()];
6238
- case 2:
6239
- availableModels = _d.sent();
6240
- availableModelNames = availableModels
6241
- .filter(function (_a) {
6242
- var modelVariant = _a.modelVariant;
6243
- return modelVariant === 'CHAT';
6244
- })
6245
- .map(function (_a) {
6246
- var modelName = _a.modelName;
6247
- return modelName;
6248
- })
6249
- .join(',');
6250
- return [4 /*yield*/, preparePersonaExecutor({ availableModelNames: availableModelNames, personaDescription: personaDescription })];
6251
- case 3:
6252
- result = _d.sent();
6253
- assertsExecutionSuccessful(result);
6254
- outputParameters = result.outputParameters;
6255
- modelRequirementsRaw = outputParameters.modelRequirements;
6256
- modelRequirements = JSON.parse(modelRequirementsRaw);
6257
- if (isVerbose) {
6258
- console.info("PERSONA ".concat(personaDescription), modelRequirements);
6259
- }
6260
- modelName = modelRequirements.modelName, systemMessage = modelRequirements.systemMessage, temperature = modelRequirements.temperature;
6261
- return [2 /*return*/, {
6262
- modelVariant: 'CHAT',
6263
- modelName: modelName,
6264
- systemMessage: systemMessage,
6265
- temperature: temperature,
6266
- }];
5597
+ ] })); });
5598
+ knowledgePreparedUnflatten[index] = pieces;
5599
+ return [2 /*return*/];
5600
+ }
5601
+ });
5602
+ }); })];
5603
+ case 1:
5604
+ _c.sent();
5605
+ knowledgePrepared = knowledgePreparedUnflatten.flat();
5606
+ return [2 /*return*/, knowledgePrepared];
6267
5607
  }
6268
5608
  });
6269
5609
  });
6270
5610
  }
5611
+ /*
5612
+ TODO: [🧊] This is how it can look in future
5613
+ > type PrepareKnowledgeKnowledge = {
5614
+ > /**
5615
+ > * Unprepared knowledge
5616
+ > * /
5617
+ > readonly knowledgeSources: Array<KnowledgeSourceJson>;
5618
+ > };
5619
+ >
5620
+ > export async function prepareKnowledgePieces(
5621
+ > knowledge: PrepareKnowledgeKnowledge,
5622
+ > options: PrepareAndScrapeOptions,
5623
+ > ):
5624
+ */
6271
5625
  /**
6272
- * TODO: [🔃][main] !!!!! If the persona was prepared with different version or different set of models, prepare it once again
6273
- * TODO: [🏢] !! Check validity of `modelName` in pipeline
6274
- * TODO: [🏢] !! Check validity of `systemMessage` in pipeline
6275
- * TODO: [🏢] !! Check validity of `temperature` in pipeline
5626
+ * TODO: [🧊] In future one preparation can take data from previous preparation and save tokens and time
5627
+ * Put `knowledgePieces` into `PrepareKnowledgeOptions`
5628
+ * TODO: [🪂] More than max things can run in parallel by acident [1,[2a,2b,_],[3a,3b,_]]
5629
+ * TODO: [🧠][❎] Do here propper M:N mapping
5630
+ * [x] One source can make multiple pieces
5631
+ * [ ] One piece can have multiple sources
6276
5632
  */
6277
5633
 
6278
5634
  /**
@@ -6309,7 +5665,7 @@ function clonePipeline(pipeline) {
6309
5665
  *
6310
5666
  * @public exported from `@promptbook/core`
6311
5667
  */
6312
- function prepareTemplates(pipeline, options) {
5668
+ function prepareTemplates(pipeline, tools, options) {
6313
5669
  return __awaiter(this, void 0, void 0, function () {
6314
5670
  var _a, maxParallelCount, templates, parameters, knowledgePiecesCount, templatesPrepared;
6315
5671
  var _this = this;
@@ -6320,9 +5676,7 @@ function prepareTemplates(pipeline, options) {
6320
5676
  templates = pipeline.templates, parameters = pipeline.parameters, knowledgePiecesCount = pipeline.knowledgePiecesCount;
6321
5677
  // TODO: [main] !!!!! Apply samples to each template (if missing and is for the template defined)
6322
5678
  TODO_USE(parameters);
6323
- templatesPrepared = new Array(
6324
- // <- TODO: [🧱] Implement in a functional (not new Class) way
6325
- templates.length);
5679
+ templatesPrepared = new Array(templates.length);
6326
5680
  return [4 /*yield*/, forEachAsync(templates, { maxParallelCount: maxParallelCount /* <- TODO: [🪂] When there are subtasks, this maximul limit can be broken */ }, function (template, index) { return __awaiter(_this, void 0, void 0, function () {
6327
5681
  var dependentParameterNames, preparedContent, preparedTemplate;
6328
5682
  return __generator(this, function (_a) {
@@ -6365,14 +5719,14 @@ function prepareTemplates(pipeline, options) {
6365
5719
  * Note: When the pipeline is already prepared, it returns the same pipeline
6366
5720
  * @public exported from `@promptbook/core`
6367
5721
  */
6368
- function preparePipeline(pipeline, options) {
5722
+ function preparePipeline(pipeline, tools, options) {
6369
5723
  return __awaiter(this, void 0, void 0, function () {
6370
- var llmTools, rootDirname, _a, maxParallelCount, _b, isVerbose, parameters, templates,
5724
+ var rootDirname, _a, maxParallelCount, _b, isVerbose, parameters, templates,
6371
5725
  /*
6372
5726
  <- TODO: [🧠][🪑] `promptbookVersion` */
6373
5727
  knowledgeSources /*
6374
5728
  <- TODO: [🧊] `knowledgePieces` */, personas /*
6375
- <- TODO: [🧊] `preparations` */, llmToolsWithUsage, currentPreparation, preparations, preparedPersonas, knowledgeSourcesPrepared, partialknowledgePiecesPrepared, knowledgePiecesPrepared, templatesPrepared /* TODO: parameters: parametersPrepared*/;
5729
+ <- TODO: [🧊] `preparations` */, _llms, llmTools, llmToolsWithUsage, currentPreparation, preparations, preparedPersonas, knowledgeSourcesPrepared, partialknowledgePiecesPrepared, knowledgePiecesPrepared, templatesPrepared /* TODO: parameters: parametersPrepared*/;
6376
5730
  var _this = this;
6377
5731
  return __generator(this, function (_c) {
6378
5732
  switch (_c.label) {
@@ -6380,11 +5734,13 @@ function preparePipeline(pipeline, options) {
6380
5734
  if (isPipelinePrepared(pipeline)) {
6381
5735
  return [2 /*return*/, pipeline];
6382
5736
  }
6383
- llmTools = options.llmTools, rootDirname = options.rootDirname, _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? MAX_PARALLEL_COUNT : _a, _b = options.isVerbose, isVerbose = _b === void 0 ? IS_VERBOSE : _b;
5737
+ rootDirname = options.rootDirname, _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? MAX_PARALLEL_COUNT : _a, _b = options.isVerbose, isVerbose = _b === void 0 ? IS_VERBOSE : _b;
6384
5738
  parameters = pipeline.parameters, templates = pipeline.templates, knowledgeSources = pipeline.knowledgeSources, personas = pipeline.personas;
6385
- if (llmTools === undefined) {
5739
+ if (tools === undefined || tools.llm === undefined) {
6386
5740
  throw new MissingToolsError('LLM tools are required for preparing the pipeline');
6387
5741
  }
5742
+ _llms = arrayableToArray(tools.llm);
5743
+ llmTools = _llms.length === 1 ? _llms[0] : joinLlmExecutionTools.apply(void 0, __spreadArray([], __read(_llms), false));
6388
5744
  llmToolsWithUsage = countTotalUsage(llmTools);
6389
5745
  currentPreparation = {
6390
5746
  id: 1,
@@ -6397,15 +5753,12 @@ function preparePipeline(pipeline, options) {
6397
5753
  // <- TODO: [🧊]
6398
5754
  currentPreparation,
6399
5755
  ];
6400
- preparedPersonas = new Array(
6401
- // <- TODO: [🧱] Implement in a functional (not new Class) way
6402
- personas.length);
5756
+ preparedPersonas = new Array(personas.length);
6403
5757
  return [4 /*yield*/, forEachAsync(personas, { maxParallelCount: maxParallelCount /* <- TODO: [🪂] When there are subtasks, this maximul limit can be broken */ }, function (persona, index) { return __awaiter(_this, void 0, void 0, function () {
6404
5758
  var modelRequirements, preparedPersona;
6405
5759
  return __generator(this, function (_a) {
6406
5760
  switch (_a.label) {
6407
- case 0: return [4 /*yield*/, preparePersona(persona.description, {
6408
- llmTools: llmToolsWithUsage,
5761
+ case 0: return [4 /*yield*/, preparePersona(persona.description, __assign(__assign({}, tools), { llm: llmToolsWithUsage }), {
6409
5762
  rootDirname: rootDirname,
6410
5763
  maxParallelCount: maxParallelCount /* <- TODO: [🪂] */,
6411
5764
  isVerbose: isVerbose,
@@ -6421,7 +5774,7 @@ function preparePipeline(pipeline, options) {
6421
5774
  case 1:
6422
5775
  _c.sent();
6423
5776
  knowledgeSourcesPrepared = knowledgeSources.map(function (source) { return (__assign(__assign({}, source), { preparationIds: [/* TODO: [🧊] -> */ currentPreparation.id] })); });
6424
- return [4 /*yield*/, prepareKnowledgePieces(knowledgeSources /* <- TODO: [🧊] {knowledgeSources, knowledgePieces} */, __assign(__assign({}, options), { llmTools: llmToolsWithUsage, rootDirname: rootDirname, maxParallelCount: maxParallelCount /* <- TODO: [🪂] */, isVerbose: isVerbose }))];
5777
+ return [4 /*yield*/, prepareKnowledgePieces(knowledgeSources /* <- TODO: [🧊] {knowledgeSources, knowledgePieces} */, __assign(__assign({}, tools), { llm: llmToolsWithUsage }), __assign(__assign({}, options), { rootDirname: rootDirname, maxParallelCount: maxParallelCount /* <- TODO: [🪂] */, isVerbose: isVerbose }))];
6425
5778
  case 2:
6426
5779
  partialknowledgePiecesPrepared = _c.sent();
6427
5780
  knowledgePiecesPrepared = partialknowledgePiecesPrepared.map(function (piece) { return (__assign(__assign({}, piece), { preparationIds: [/* TODO: [🧊] -> */ currentPreparation.id] })); });
@@ -6429,8 +5782,7 @@ function preparePipeline(pipeline, options) {
6429
5782
  parameters: parameters,
6430
5783
  templates: templates,
6431
5784
  knowledgePiecesCount: knowledgePiecesPrepared.length,
6432
- }, {
6433
- llmTools: llmToolsWithUsage,
5785
+ }, __assign(__assign({}, tools), { llm: llmToolsWithUsage }), {
6434
5786
  rootDirname: rootDirname,
6435
5787
  maxParallelCount: maxParallelCount /* <- TODO: [🪂] */,
6436
5788
  isVerbose: isVerbose,
@@ -6959,72 +6311,6 @@ var expectCommandParser = {
6959
6311
  },
6960
6312
  };
6961
6313
 
6962
- /**
6963
- * @@@
6964
- *
6965
- * @param text @@@
6966
- * @returns @@@
6967
- * @example 'HELLO_WORLD'
6968
- * @example 'I_LOVE_PROMPTBOOK'
6969
- * @public exported from `@promptbook/utils`
6970
- */
6971
- function normalizeTo_SCREAMING_CASE(text) {
6972
- var e_1, _a;
6973
- var charType;
6974
- var lastCharType = 'OTHER';
6975
- var normalizedName = '';
6976
- try {
6977
- for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
6978
- var char = text_1_1.value;
6979
- var normalizedChar = void 0;
6980
- if (/^[a-z]$/.test(char)) {
6981
- charType = 'LOWERCASE';
6982
- normalizedChar = char.toUpperCase();
6983
- }
6984
- else if (/^[A-Z]$/.test(char)) {
6985
- charType = 'UPPERCASE';
6986
- normalizedChar = char;
6987
- }
6988
- else if (/^[0-9]$/.test(char)) {
6989
- charType = 'NUMBER';
6990
- normalizedChar = char;
6991
- }
6992
- else {
6993
- charType = 'OTHER';
6994
- normalizedChar = '_';
6995
- }
6996
- if (charType !== lastCharType &&
6997
- !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
6998
- !(lastCharType === 'NUMBER') &&
6999
- !(charType === 'NUMBER')) {
7000
- normalizedName += '_';
7001
- }
7002
- normalizedName += normalizedChar;
7003
- lastCharType = charType;
7004
- }
7005
- }
7006
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
7007
- finally {
7008
- try {
7009
- if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
7010
- }
7011
- finally { if (e_1) throw e_1.error; }
7012
- }
7013
- normalizedName = normalizedName.replace(/_+/g, '_');
7014
- normalizedName = normalizedName.replace(/_?\/_?/g, '/');
7015
- normalizedName = normalizedName.replace(/^_/, '');
7016
- normalizedName = normalizedName.replace(/_$/, '');
7017
- return normalizedName;
7018
- }
7019
- /**
7020
- * TODO: Tests
7021
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'Moje tabule' })).toEqual('/VtG7sR9rRJqwNEdM2/Moje tabule');
7022
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'ěščřžžýáíúů' })).toEqual('/VtG7sR9rRJqwNEdM2/escrzyaieuu');
7023
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj');
7024
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj_ahojAhoj ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj-ahoj-ahoj-ahoj');
7025
- * TODO: [🌺] Use some intermediate util splitWords
7026
- */
7027
-
7028
6314
  /**
7029
6315
  * @@@
7030
6316
  *
@@ -7089,6 +6375,22 @@ function normalizeTo_camelCase(text, _isFirstLetterCapital) {
7089
6375
  * TODO: [🌺] Use some intermediate util splitWords
7090
6376
  */
7091
6377
 
6378
+ /**
6379
+ * Removes emojis from a string and fix whitespaces
6380
+ *
6381
+ * @param text with emojis
6382
+ * @returns text without emojis
6383
+ * @public exported from `@promptbook/utils`
6384
+ */
6385
+ function removeEmojis(text) {
6386
+ // Replace emojis (and also ZWJ sequence) with hyphens
6387
+ text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
6388
+ text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
6389
+ text = text.replace(/(\p{Extended_Pictographic})(\u{200D}\p{Extended_Pictographic})*/gu, '$1');
6390
+ text = text.replace(/\p{Extended_Pictographic}/gu, '');
6391
+ return text;
6392
+ }
6393
+
7092
6394
  /**
7093
6395
  * Removes quotes from a string
7094
6396
  *
@@ -8836,6 +8138,30 @@ function removeContentComments(content) {
8836
8138
  return spaceTrim$1(content.replace(/<!--(.*?)-->/gs, ''));
8837
8139
  }
8838
8140
 
8141
+ /**
8142
+ * @@@
8143
+ *
8144
+ * @param value @@@
8145
+ * @returns @@@
8146
+ * @example @@@
8147
+ * @public exported from `@promptbook/utils`
8148
+ */
8149
+ function titleToName(value) {
8150
+ if (isValidUrl(value)) {
8151
+ value = value.replace(/^https?:\/\//, '');
8152
+ value = value.replace(/\.html$/, '');
8153
+ }
8154
+ else if (isValidFilePath(value)) {
8155
+ value = basename(value);
8156
+ // Note: Keeping extension in the name
8157
+ }
8158
+ value = value.split('/').join('-');
8159
+ value = removeEmojis(value);
8160
+ value = normalizeToKebabCase(value);
8161
+ // TODO: [🧠] Maybe warn or add some padding to short name which are not good identifiers
8162
+ return value;
8163
+ }
8164
+
8839
8165
  /**
8840
8166
  * Compile pipeline from string (markdown) format to JSON format synchronously
8841
8167
  *
@@ -9170,21 +8496,21 @@ function pipelineStringToJsonSync(pipelineString) {
9170
8496
  * Note: This function acts as compilation process
9171
8497
  *
9172
8498
  * @param pipelineString {Promptbook} in string markdown format (.ptbk.md)
8499
+ * @param tools - Tools for the preparation and scraping - if not provided together with `llm`, the preparation will be skipped
9173
8500
  * @param options - Options and tools for the compilation
9174
8501
  * @returns {Promptbook} compiled in JSON format (.ptbk.json)
9175
8502
  * @throws {ParseError} if the promptbook string is not valid
9176
8503
  * @public exported from `@promptbook/core`
9177
8504
  */
9178
- function pipelineStringToJson(pipelineString, options) {
8505
+ function pipelineStringToJson(pipelineString, tools, options) {
9179
8506
  return __awaiter(this, void 0, void 0, function () {
9180
- var llmTools, pipelineJson;
8507
+ var pipelineJson;
9181
8508
  return __generator(this, function (_a) {
9182
8509
  switch (_a.label) {
9183
8510
  case 0:
9184
- llmTools = (options || {}).llmTools;
9185
8511
  pipelineJson = pipelineStringToJsonSync(pipelineString);
9186
- if (!(llmTools !== undefined)) return [3 /*break*/, 2];
9187
- return [4 /*yield*/, preparePipeline(pipelineJson, options || {
8512
+ if (!(tools !== undefined && tools.llm !== undefined)) return [3 /*break*/, 2];
8513
+ return [4 /*yield*/, preparePipeline(pipelineJson, tools, options || {
9188
8514
  rootDirname: null,
9189
8515
  })];
9190
8516
  case 1:
@@ -9501,56 +8827,6 @@ function usageToHuman(usage) {
9501
8827
  * TODO: [🏛] Maybe make some markdown builder
9502
8828
  */
9503
8829
 
9504
- /**
9505
- * @@@
9506
- *
9507
- * Note: `$` is used to indicate that this function is not a pure function - it access global scope
9508
- *
9509
- * @private internal function of `$Register`
9510
- */
9511
- function $getGlobalScope() {
9512
- return Function('return this')();
9513
- }
9514
-
9515
- /**
9516
- * Register is @@@
9517
- *
9518
- * Note: `$` is used to indicate that this function is not a pure function - it accesses and adds variables in global scope.
9519
- *
9520
- * @private internal utility, exported are only signleton instances of this class
9521
- */
9522
- var $Register = /** @class */ (function () {
9523
- function $Register(storageName) {
9524
- this.storageName = storageName;
9525
- storageName = "_promptbook_".concat(storageName);
9526
- var globalScope = $getGlobalScope();
9527
- if (globalScope[storageName] === undefined) {
9528
- globalScope[storageName] = [];
9529
- }
9530
- else if (!Array.isArray(globalScope[storageName])) {
9531
- throw new UnexpectedError("Expected (global) ".concat(storageName, " to be an array, but got ").concat(typeof globalScope[storageName]));
9532
- }
9533
- this.storage = globalScope[storageName];
9534
- }
9535
- $Register.prototype.list = function () {
9536
- // <- TODO: ReadonlyDeep<Array<TRegistered>>
9537
- return this.storage;
9538
- };
9539
- $Register.prototype.register = function (registered) {
9540
- // <- TODO: What to return here
9541
- var packageName = registered.packageName, className = registered.className;
9542
- var existingRegistrationIndex = this.storage.findIndex(function (item) { return item.packageName === packageName && item.className === className; });
9543
- var existingRegistration = this.storage[existingRegistrationIndex];
9544
- if (!existingRegistration) {
9545
- this.storage.push(registered);
9546
- }
9547
- else {
9548
- this.storage[existingRegistrationIndex] = registered;
9549
- }
9550
- };
9551
- return $Register;
9552
- }());
9553
-
9554
8830
  /**
9555
8831
  * @@@
9556
8832
  *
@@ -9559,6 +8835,9 @@ var $Register = /** @class */ (function () {
9559
8835
  * @public exported from `@promptbook/core`
9560
8836
  */
9561
8837
  var $llmToolsMetadataRegister = new $Register('llm_tools_metadata');
8838
+ /**
8839
+ * TODO: [®] DRY Register logic
8840
+ */
9562
8841
 
9563
8842
  /**
9564
8843
  * @@@
@@ -9568,13 +8847,16 @@ var $llmToolsMetadataRegister = new $Register('llm_tools_metadata');
9568
8847
  * @public exported from `@promptbook/core`
9569
8848
  */
9570
8849
  var $llmToolsRegister = new $Register('llm_execution_tools_constructors');
8850
+ /**
8851
+ * TODO: [®] DRY Register logic
8852
+ */
9571
8853
 
9572
8854
  /**
9573
8855
  * Creates a message with all registered LLM tools
9574
8856
  *
9575
8857
  * Note: This function is used to create a (error) message when there is no constructor for some LLM provider
9576
8858
  *
9577
- * @private internal function of `createLlmToolsFromConfiguration` and `createLlmToolsFromEnv`
8859
+ * @private internal function of `createLlmToolsFromConfiguration` and `$provideLlmToolsFromEnv`
9578
8860
  */
9579
8861
  function $registeredLlmToolsMessage() {
9580
8862
  var e_1, _a, e_2, _b;
@@ -9666,6 +8948,9 @@ function $registeredLlmToolsMessage() {
9666
8948
  })
9667
8949
  .join('\n')), "\n "); });
9668
8950
  }
8951
+ /**
8952
+ * TODO: [®] DRY Register logic
8953
+ */
9669
8954
 
9670
8955
  /**
9671
8956
  * @@@
@@ -9693,12 +8978,13 @@ function createLlmToolsFromConfiguration(configuration, options) {
9693
8978
  return joinLlmExecutionTools.apply(void 0, __spreadArray([], __read(llmTools), false));
9694
8979
  }
9695
8980
  /**
9696
- * TODO: [🎌] Togethere with `createLlmToolsFromConfiguration` + 'EXECUTION_TOOLS_CLASSES' gets to `@promptbook/core` ALL model providers, make this more efficient
8981
+ * TODO: [🎌] Together with `createLlmToolsFromConfiguration` + 'EXECUTION_TOOLS_CLASSES' gets to `@promptbook/core` ALL model providers, make this more efficient
9697
8982
  * TODO: [🧠][🎌] Dynamically install required providers
9698
8983
  * TODO: @@@ write discussion about this - wizzard
9699
8984
  * TODO: [🧠][🍛] Which name is better `createLlmToolsFromConfig` or `createLlmToolsFromConfiguration`?
9700
8985
  * TODO: [🧠] Is there some meaningfull way how to test this util
9701
8986
  * TODO: This should be maybe not under `_common` but under `utils`
8987
+ * TODO: [®] DRY Register logic
9702
8988
  */
9703
8989
 
9704
8990
  /**
@@ -9777,11 +9063,7 @@ function $currentDate() {
9777
9063
  function cacheLlmTools(llmTools, options) {
9778
9064
  var _this = this;
9779
9065
  if (options === void 0) { options = {}; }
9780
- var _a = options.storage, storage = _a === void 0 ? new MemoryStorage() : _a,
9781
- // <- TODO: [🧱] Implement in a functional (not new Class) way
9782
- _b = options.isReloaded,
9783
- // <- TODO: [🧱] Implement in a functional (not new Class) way
9784
- isReloaded = _b === void 0 ? false : _b;
9066
+ var _a = options.storage, storage = _a === void 0 ? new MemoryStorage() : _a, _b = options.isReloaded, isReloaded = _b === void 0 ? false : _b;
9785
9067
  var proxyTools = __assign(__assign({}, llmTools), {
9786
9068
  // <- Note: [🥫]
9787
9069
  get title() {
@@ -9931,9 +9213,9 @@ function limitTotalUsage(llmTools, options) {
9931
9213
  */
9932
9214
 
9933
9215
  /**
9934
- * @@@ registration1 of default configuration for Anthropic Claude
9216
+ * Registration of LLM provider metadata
9935
9217
  *
9936
- * Note: [🏐] Configurations registrations are done in @@@ BUT constructor @@@
9218
+ * Warning: This is not useful for the end user, it is just a side effect of the mechanism that handles all available LLM tools
9937
9219
  *
9938
9220
  * @public exported from `@promptbook/core`
9939
9221
  * @public exported from `@promptbook/cli`
@@ -9972,9 +9254,9 @@ var _AnthropicClaudeMetadataRegistration = $llmToolsMetadataRegister.register({
9972
9254
  });
9973
9255
 
9974
9256
  /**
9975
- * @@@ registration1 of default configuration for Azure Open AI
9257
+ * Registration of LLM provider metadata
9976
9258
  *
9977
- * Note: [🏐] Configurations registrations are done in @@@ BUT constructor @@@
9259
+ * Warning: This is not useful for the end user, it is just a side effect of the mechanism that handles all available LLM tools
9978
9260
  *
9979
9261
  * @public exported from `@promptbook/core`
9980
9262
  * @public exported from `@promptbook/cli`
@@ -10019,9 +9301,9 @@ var _AzureOpenAiMetadataRegistration = $llmToolsMetadataRegister.register({
10019
9301
  });
10020
9302
 
10021
9303
  /**
10022
- * @@@ registration1 of default configuration for Open AI
9304
+ * Registration of LLM provider metadata
10023
9305
  *
10024
- * Note: [🏐] Configurations registrations are done in @@@ BUT constructor @@@
9306
+ * Warning: This is not useful for the end user, it is just a side effect of the mechanism that handles all available LLM tools
10025
9307
  *
10026
9308
  * @public exported from `@promptbook/core`
10027
9309
  * @public exported from `@promptbook/cli`
@@ -10100,6 +9382,126 @@ var _OpenAiAssistantMetadataRegistration = $llmToolsMetadataRegister.register({
10100
9382
  },
10101
9383
  });
10102
9384
 
9385
+ /**
9386
+ * Metadata of the scraper
9387
+ *
9388
+ * @private within the scraper directory
9389
+ */
9390
+ var legacyDocumentScraperMetadata = $deepFreeze({
9391
+ title: 'LegacyDocument scraper',
9392
+ packageName: '@promptbook/legacy-documents',
9393
+ className: 'LegacyDocumentScraper',
9394
+ mimeTypes: ['application/msword', 'text/rtf'],
9395
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
9396
+ isAvilableInBrowser: false,
9397
+ requiredExecutables: ['!!!!!!'],
9398
+ }); /* <- TODO: [🤛] */
9399
+ /**
9400
+ * Registration of known scraper metadata
9401
+ *
9402
+ * Warning: This is not useful for the end user, it is just a side effect of the mechanism that handles all available known scrapers
9403
+ *
9404
+ * @public exported from `@promptbook/core`
9405
+ * @public exported from `@promptbook/cli`
9406
+ */
9407
+ var _LegacyDocumentScraperMetadataRegistration = $scrapersMetadataRegister.register(legacyDocumentScraperMetadata);
9408
+
9409
+ /**
9410
+ * Metadata of the scraper
9411
+ *
9412
+ * @private within the scraper directory
9413
+ */
9414
+ var documentScraperMetadata = $deepFreeze({
9415
+ title: 'Document scraper',
9416
+ packageName: '@promptbook/documents',
9417
+ className: 'DocumentScraper',
9418
+ mimeTypes: ['application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
9419
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
9420
+ isAvilableInBrowser: false,
9421
+ requiredExecutables: ['!!!!!!'],
9422
+ }); /* <- TODO: [🤛] */
9423
+ /**
9424
+ * Registration of known scraper metadata
9425
+ *
9426
+ * Warning: This is not useful for the end user, it is just a side effect of the mechanism that handles all available known scrapers
9427
+ *
9428
+ * @public exported from `@promptbook/core`
9429
+ * @public exported from `@promptbook/cli`
9430
+ */
9431
+ var _DocumentScraperMetadataRegistration = $scrapersMetadataRegister.register(documentScraperMetadata);
9432
+
9433
+ /**
9434
+ * Metadata of the scraper
9435
+ *
9436
+ * @private within the scraper directory
9437
+ */
9438
+ var markdownScraperMetadata = $deepFreeze({
9439
+ title: 'Markdown scraper',
9440
+ packageName: '@promptbook/markdown-utils',
9441
+ className: 'MarkdownScraper',
9442
+ mimeTypes: ['text/markdown', 'text/plain'],
9443
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
9444
+ isAvilableInBrowser: true,
9445
+ requiredExecutables: ['!!!!!!'],
9446
+ }); /* <- TODO: [🤛] */
9447
+ /**
9448
+ * Registration of known scraper metadata
9449
+ *
9450
+ * Warning: This is not useful for the end user, it is just a side effect of the mechanism that handles all available known scrapers
9451
+ *
9452
+ * @public exported from `@promptbook/core`
9453
+ * @public exported from `@promptbook/cli`
9454
+ */
9455
+ var _MarkdownScraperMetadataRegistration = $scrapersMetadataRegister.register(markdownScraperMetadata);
9456
+
9457
+ /**
9458
+ * Metadata of the scraper
9459
+ *
9460
+ * @private within the scraper directory
9461
+ */
9462
+ var pdfScraperMetadata = $deepFreeze({
9463
+ title: 'Pdf scraper',
9464
+ packageName: '@promptbook/pdf',
9465
+ className: 'PdfScraper',
9466
+ mimeTypes: ['application/pdf'],
9467
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
9468
+ isAvilableInBrowser: true,
9469
+ requiredExecutables: ['!!!!!!'],
9470
+ }); /* <- TODO: [🤛] */
9471
+ /**
9472
+ * Registration of known scraper metadata
9473
+ *
9474
+ * Warning: This is not useful for the end user, it is just a side effect of the mechanism that handles all available known scrapers
9475
+ *
9476
+ * @public exported from `@promptbook/core`
9477
+ * @public exported from `@promptbook/cli`
9478
+ */
9479
+ var _PdfScraperMetadataRegistration = $scrapersMetadataRegister.register(pdfScraperMetadata);
9480
+
9481
+ /**
9482
+ * Metadata of the scraper
9483
+ *
9484
+ * @private within the scraper directory
9485
+ */
9486
+ var websiteScraperMetadata = $deepFreeze({
9487
+ title: 'Website scraper',
9488
+ packageName: '@promptbook/website-crawler',
9489
+ className: 'WebsiteScraper',
9490
+ mimeTypes: ['text/html'],
9491
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
9492
+ isAvilableInBrowser: false,
9493
+ requiredExecutables: ['!!!!!!'],
9494
+ }); /* <- TODO: [🤛] */
9495
+ /**
9496
+ * Registration of known scraper metadata
9497
+ *
9498
+ * Warning: This is not useful for the end user, it is just a side effect of the mechanism that handles all available known scrapers
9499
+ *
9500
+ * @public exported from `@promptbook/core`
9501
+ * @public exported from `@promptbook/cli`
9502
+ */
9503
+ var _WebsiteScraperMetadataRegistration = $scrapersMetadataRegister.register(websiteScraperMetadata);
9504
+
10103
9505
  /**
10104
9506
  * This class behaves like LocalStorage but separates keys by prefix
10105
9507
  *
@@ -10450,5 +9852,5 @@ function executionReportJsonToString(executionReportJson, options) {
10450
9852
  * TODO: [🧠] Should be in generated file GENERATOR_WARNING
10451
9853
  */
10452
9854
 
10453
- export { $llmToolsMetadataRegister, $llmToolsRegister, AbstractFormatError, CLAIM, CallbackInterfaceTools, CollectionError, CsvFormatDefinition, CsvFormatError, DEFAULT_CSV_SETTINGS, DEFAULT_REMOTE_URL, DEFAULT_REMOTE_URL_PATH, ERRORS, EXECUTIONS_CACHE_DIRNAME, EXPECTATION_UNITS, EnvironmentMismatchError, ExecutionReportStringOptionsDefaults, ExpectError, IS_VERBOSE, KnowledgeScrapeError, LimitReachedError, MANDATORY_CSV_SETTINGS, MAX_EXECUTION_ATTEMPTS, MAX_FILENAME_LENGTH, MAX_KNOWLEDGE_SOURCES_SCRAPING_DEPTH, MAX_KNOWLEDGE_SOURCES_SCRAPING_TOTAL, MAX_PARALLEL_COUNT, MODEL_VARIANTS, MemoryStorage, MissingToolsError, NotFoundError, NotYetImplementedError, PIPELINE_COLLECTION_BASE_FILENAME, PROMPTBOOK_VERSION, ParseError, PipelineExecutionError, PipelineLogicError, PipelineUrlError, PrefixStorage, RESERVED_PARAMETER_NAMES, SCRAPE_CACHE_DIRNAME, TemplateTypes, TextFormatDefinition, UNCERTAIN_USAGE, UnexpectedError, ZERO_USAGE, _AnthropicClaudeMetadataRegistration, _AzureOpenAiMetadataRegistration, _OpenAiAssistantMetadataRegistration, _OpenAiMetadataRegistration, addUsage, assertsExecutionSuccessful, cacheLlmTools, collectionToJson, countTotalUsage, createCollectionFromJson, createCollectionFromPromise, createCollectionFromUrl, createLlmToolsFromConfiguration, createPipelineExecutor, createSubcollection, documentScraper, embeddingVectorToString, executionReportJsonToString, isPassingExpectations, isPipelinePrepared, joinLlmExecutionTools, legacyDocumentScraper, limitTotalUsage, markdownScraper, pdfScraper, pipelineJsonToString, pipelineStringToJson, pipelineStringToJsonSync, prepareKnowledgePieces, preparePersona, preparePipeline, prepareTemplates, prettifyPipelineString, stringifyPipelineJson, unpreparePipeline, usageToHuman, usageToWorktime, validatePipeline, websiteScraper };
9855
+ export { $llmToolsMetadataRegister, $llmToolsRegister, $scrapersMetadataRegister, $scrapersRegister, AbstractFormatError, CLAIM, CallbackInterfaceTools, CollectionError, CsvFormatDefinition, CsvFormatError, DEFAULT_CSV_SETTINGS, DEFAULT_REMOTE_URL, DEFAULT_REMOTE_URL_PATH, ERRORS, EXECUTIONS_CACHE_DIRNAME, EXPECTATION_UNITS, EnvironmentMismatchError, ExecutionReportStringOptionsDefaults, ExpectError, IS_AUTO_INSTALLED, IS_VERBOSE, KnowledgeScrapeError, LimitReachedError, MANDATORY_CSV_SETTINGS, MAX_EXECUTION_ATTEMPTS, MAX_FILENAME_LENGTH, MAX_KNOWLEDGE_SOURCES_SCRAPING_DEPTH, MAX_KNOWLEDGE_SOURCES_SCRAPING_TOTAL, MAX_PARALLEL_COUNT, MODEL_VARIANTS, MemoryStorage, MissingToolsError, NotFoundError, NotYetImplementedError, PIPELINE_COLLECTION_BASE_FILENAME, PROMPTBOOK_VERSION, ParseError, PipelineExecutionError, PipelineLogicError, PipelineUrlError, PrefixStorage, RESERVED_PARAMETER_NAMES, SCRAPE_CACHE_DIRNAME, TemplateTypes, TextFormatDefinition, UNCERTAIN_USAGE, UnexpectedError, ZERO_USAGE, _AnthropicClaudeMetadataRegistration, _AzureOpenAiMetadataRegistration, _DocumentScraperMetadataRegistration, _LegacyDocumentScraperMetadataRegistration, _MarkdownScraperMetadataRegistration, _OpenAiAssistantMetadataRegistration, _OpenAiMetadataRegistration, _PdfScraperMetadataRegistration, _WebsiteScraperMetadataRegistration, addUsage, assertsExecutionSuccessful, cacheLlmTools, collectionToJson, countTotalUsage, createCollectionFromJson, createCollectionFromPromise, createCollectionFromUrl, createLlmToolsFromConfiguration, createPipelineExecutor, createSubcollection, embeddingVectorToString, executionReportJsonToString, isPassingExpectations, isPipelinePrepared, joinLlmExecutionTools, limitTotalUsage, pipelineJsonToString, pipelineStringToJson, pipelineStringToJsonSync, prepareKnowledgePieces, preparePersona, preparePipeline, prepareTemplates, prettifyPipelineString, stringifyPipelineJson, unpreparePipeline, usageToHuman, usageToWorktime, validatePipeline };
10454
9856
  //# sourceMappingURL=index.es.js.map