@promptbook/core 0.72.0-0 → 0.72.0-1

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 (65) hide show
  1. package/README.md +5 -6
  2. package/esm/index.es.js +2204 -1360
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/src/_packages/cli.index.d.ts +4 -0
  5. package/esm/typings/src/_packages/core.index.d.ts +11 -1
  6. package/esm/typings/src/_packages/openai.index.d.ts +4 -0
  7. package/esm/typings/src/_packages/types.index.d.ts +12 -0
  8. package/esm/typings/src/_packages/utils.index.d.ts +4 -4
  9. package/esm/typings/src/commands/FOREACH/ForeachCommand.d.ts +3 -2
  10. package/esm/typings/src/commands/FOREACH/ForeachJson.d.ts +23 -0
  11. package/esm/typings/src/commands/FOREACH/foreachCommandParser.d.ts +1 -1
  12. package/esm/typings/src/commands/_common/types/CommandParser.d.ts +16 -1
  13. package/esm/typings/src/config.d.ts +14 -1
  14. package/esm/typings/src/conversion/prettify/renderPipelineMermaidOptions.d.ts +3 -0
  15. package/esm/typings/src/conversion/utils/extractParameterNamesFromTemplate.d.ts +2 -1
  16. package/esm/typings/src/conversion/validation/validatePipeline.d.ts +5 -0
  17. package/esm/typings/src/execution/PipelineExecutorResult.d.ts +9 -8
  18. package/esm/typings/src/execution/createPipelineExecutor/$OngoingTemplateResult.d.ts +45 -0
  19. package/esm/typings/src/execution/createPipelineExecutor/00-CreatePipelineExecutorOptions.d.ts +20 -0
  20. package/esm/typings/src/execution/createPipelineExecutor/00-CreatePipelineExecutorSettings.d.ts +40 -0
  21. package/esm/typings/src/execution/createPipelineExecutor/00-createPipelineExecutor.d.ts +10 -0
  22. package/esm/typings/src/execution/createPipelineExecutor/10-executePipeline.d.ts +55 -0
  23. package/esm/typings/src/execution/createPipelineExecutor/20-executeTemplate.d.ts +62 -0
  24. package/esm/typings/src/execution/createPipelineExecutor/30-executeFormatCells.d.ts +19 -0
  25. package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempts.d.ts +74 -0
  26. package/esm/typings/src/execution/createPipelineExecutor/filterJustOutputParameters.d.ts +34 -0
  27. package/esm/typings/src/execution/createPipelineExecutor/getContextForTemplate.d.ts +10 -0
  28. package/esm/typings/src/execution/createPipelineExecutor/getKnowledgeForTemplate.d.ts +27 -0
  29. package/esm/typings/src/execution/createPipelineExecutor/getReservedParametersForTemplate.d.ts +30 -0
  30. package/esm/typings/src/execution/createPipelineExecutor/getSamplesForTemplate.d.ts +10 -0
  31. package/esm/typings/src/execution/utils/checkExpectations.d.ts +2 -0
  32. package/esm/typings/src/execution/utils/usageToHuman.d.ts +3 -4
  33. package/esm/typings/src/formats/_common/FormatDefinition.d.ts +14 -15
  34. package/esm/typings/src/formats/_common/FormatSubvalueDefinition.d.ts +30 -0
  35. package/esm/typings/src/formats/csv/{ListFormatDefinition.d.ts → CsvFormatDefinition.d.ts} +6 -3
  36. package/esm/typings/src/formats/csv/CsvSettings.d.ts +13 -0
  37. package/esm/typings/src/formats/index.d.ts +1 -1
  38. package/esm/typings/src/formats/json/JsonFormatDefinition.d.ts +4 -3
  39. package/esm/typings/src/formats/text/TextFormatDefinition.d.ts +19 -0
  40. package/esm/typings/src/formats/xml/XmlFormatDefinition.d.ts +4 -3
  41. package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionTools.d.ts +1 -1
  42. package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionToolsOptions.d.ts +1 -1
  43. package/esm/typings/src/llm-providers/openai/OpenAiExecutionTools.d.ts +9 -0
  44. package/esm/typings/src/llm-providers/openai/createOpenAiAssistantExecutionTools.d.ts +15 -0
  45. package/esm/typings/src/llm-providers/openai/register-configuration.d.ts +9 -0
  46. package/esm/typings/src/llm-providers/openai/register-constructor.d.ts +9 -0
  47. package/esm/typings/src/types/PipelineJson/ParameterJson.d.ts +1 -0
  48. package/esm/typings/src/types/PipelineJson/TemplateJsonCommon.d.ts +5 -0
  49. package/esm/typings/src/types/execution-report/ExecutionReportJson.d.ts +3 -0
  50. package/esm/typings/src/utils/expectation-counters/index.d.ts +3 -0
  51. package/esm/typings/src/utils/organization/{f.d.ts → empty_object.d.ts} +5 -1
  52. package/esm/typings/src/utils/organization/just_empty_object.d.ts +12 -0
  53. package/esm/typings/src/utils/{extractParameterNames.d.ts → parameters/extractParameterNames.d.ts} +2 -2
  54. package/esm/typings/src/utils/parameters/mapAvailableToExpectedParameters.d.ts +27 -0
  55. package/esm/typings/src/utils/{replaceParameters.d.ts → parameters/replaceParameters.d.ts} +2 -2
  56. package/esm/typings/src/utils/validators/parameterName/validateParameterName.d.ts +10 -0
  57. package/esm/typings/src/utils/validators/parameterName/validateParameterName.test.d.ts +1 -0
  58. package/package.json +17 -12
  59. package/umd/index.umd.js +2211 -1363
  60. package/umd/index.umd.js.map +1 -1
  61. package/esm/typings/src/execution/createPipelineExecutor.d.ts +0 -72
  62. package/esm/typings/src/formats/list/ListFormatDefinition.d.ts +0 -16
  63. /package/esm/typings/src/utils/{extractParameterNames.test.d.ts → parameters/extractParameterNames.test.d.ts} +0 -0
  64. /package/esm/typings/src/{execution/utils/usageToHuman.test.d.ts → utils/parameters/mapAvailableToExpectedParameters.test.d.ts} +0 -0
  65. /package/esm/typings/src/utils/{replaceParameters.test.d.ts → parameters/replaceParameters.test.d.ts} +0 -0
package/esm/index.es.js CHANGED
@@ -2,6 +2,7 @@ import spaceTrim, { spaceTrim as spaceTrim$1 } from 'spacetrim';
2
2
  import { format } from 'prettier';
3
3
  import parserHtml from 'prettier/parser-html';
4
4
  import { forTime } from 'waitasecond';
5
+ import { unparse, parse } from 'papaparse';
5
6
  import hexEncoder from 'crypto-js/enc-hex';
6
7
  import sha256 from 'crypto-js/sha256';
7
8
  import moment from 'moment';
@@ -10,7 +11,7 @@ import moment from 'moment';
10
11
  /**
11
12
  * The version of the Promptbook library
12
13
  */
13
- var PROMPTBOOK_VERSION = '0.68.5';
14
+ var PROMPTBOOK_VERSION = '0.72.0-0';
14
15
  // TODO:[main] !!!! List here all the versions and annotate + put into script
15
16
 
16
17
  /*! *****************************************************************************
@@ -652,13 +653,13 @@ var IMMEDIATE_TIME = 10;
652
653
  *
653
654
  * @public exported from `@promptbook/core`
654
655
  */
655
- var MAX_PARALLEL_COUNT = 5;
656
+ var MAX_PARALLEL_COUNT = 5; // <- TODO: [🤹‍♂️]
656
657
  /**
657
658
  * The maximum number of attempts to execute LLM task before giving up
658
659
  *
659
660
  * @public exported from `@promptbook/core`
660
661
  */
661
- var MAX_EXECUTION_ATTEMPTS = 3;
662
+ var MAX_EXECUTION_ATTEMPTS = 3; // <- TODO: [🤹‍♂️]
662
663
  /**
663
664
  * The maximum length of the (generated) filename
664
665
  *
@@ -709,6 +710,7 @@ var RESERVED_PARAMETER_NAMES = $asDeeplyFrozenSerializableJson('RESERVED_PARAMET
709
710
  'samples',
710
711
  'modelName',
711
712
  'currentDate',
713
+ // <- TODO: !!!!! list here all command names
712
714
  // <- TODO: Add more like 'date', 'modelName',...
713
715
  // <- TODO: Add [emoji] + instructions ACRY when adding new reserved parameter
714
716
  ]);
@@ -746,12 +748,32 @@ var DEFAULT_REMOTE_URL = 'https://api.pavolhejny.com/';
746
748
  */
747
749
  var DEFAULT_REMOTE_URL_PATH = '/promptbook/socket.io';
748
750
  // <- TODO: [🧜‍♂️]
751
+ /**
752
+ * @@@
753
+ *
754
+ * @public exported from `@promptbook/core`
755
+ */
756
+ var DEFAULT_CSV_SETTINGS = Object.freeze({
757
+ delimiter: ',',
758
+ quoteChar: '"',
759
+ newline: '\n',
760
+ skipEmptyLines: true,
761
+ });
749
762
  /**
750
763
  * @@@
751
764
  *
752
765
  * @public exported from `@promptbook/core`
753
766
  */
754
767
  var IS_VERBOSE = false;
768
+ /**
769
+ * @@@
770
+ *
771
+ * @private within the repository
772
+ */
773
+ var IS_PIPELINE_LOGIC_VALIDATED = just(
774
+ /**/
775
+ // Note: In normal situations, we check the pipeline logic:
776
+ true);
755
777
  /**
756
778
  * TODO: [🧠][🧜‍♂️] Maybe join remoteUrl and path into single value
757
779
  */
@@ -961,6 +983,26 @@ function isValidPipelineUrl(url) {
961
983
  * @public exported from `@promptbook/core`
962
984
  */
963
985
  function validatePipeline(pipeline) {
986
+ if (IS_PIPELINE_LOGIC_VALIDATED) {
987
+ validatePipelineCore(pipeline);
988
+ }
989
+ else {
990
+ try {
991
+ validatePipelineCore(pipeline);
992
+ }
993
+ catch (error) {
994
+ if (!(error instanceof PipelineLogicError)) {
995
+ throw error;
996
+ }
997
+ console.error(spaceTrim$1(function (block) { return "\n Pipeline is not valid but logic errors are temporarily disabled via `IS_PIPELINE_LOGIC_VALIDATED`\n\n ".concat(block(error.message), "\n "); }));
998
+ }
999
+ }
1000
+ return pipeline;
1001
+ }
1002
+ /**
1003
+ * @private internal function for `validatePipeline`
1004
+ */
1005
+ function validatePipelineCore(pipeline) {
964
1006
  // TODO: [🧠] Maybe test if promptbook is a promise and make specific error case for that
965
1007
  var e_1, _a, e_2, _b, e_3, _c;
966
1008
  var pipelineIdentification = (function () {
@@ -985,12 +1027,12 @@ function validatePipeline(pipeline) {
985
1027
  // TODO: [🧠] Maybe do here some propper JSON-schema / ZOD checking
986
1028
  if (!Array.isArray(pipeline.parameters)) {
987
1029
  // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
988
- throw new ParseError(spaceTrim$1(function (block) { return "\n Promptbook is valid JSON but with wrong structure\n\n `promptbook.parameters` expected to be an array, but got ".concat(typeof pipeline.parameters, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
1030
+ throw new ParseError(spaceTrim$1(function (block) { return "\n Pipeline is valid JSON but with wrong structure\n\n `PipelineJson.parameters` expected to be an array, but got ".concat(typeof pipeline.parameters, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
989
1031
  }
990
1032
  // TODO: [🧠] Maybe do here some propper JSON-schema / ZOD checking
991
1033
  if (!Array.isArray(pipeline.templates)) {
992
1034
  // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
993
- throw new ParseError(spaceTrim$1(function (block) { return "\n Promptbook is valid JSON but with wrong structure\n\n `promptbook.templates` expected to be an array, but got ".concat(typeof pipeline.templates, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
1035
+ throw new ParseError(spaceTrim$1(function (block) { return "\n Pipeline is valid JSON but with wrong structure\n\n `PipelineJson.templates` expected to be an array, but got ".concat(typeof pipeline.templates, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
994
1036
  }
995
1037
  var _loop_1 = function (parameter) {
996
1038
  if (parameter.isInput && parameter.isOutput) {
@@ -1159,9 +1201,9 @@ function validatePipeline(pipeline) {
1159
1201
  while (unresovedTemplates.length > 0) {
1160
1202
  _loop_3();
1161
1203
  }
1162
- return pipeline;
1163
1204
  }
1164
1205
  /**
1206
+ * TODO: !!!!! [🧞‍♀️] Do not allow joker + foreach
1165
1207
  * TODO: [🧠] Work with promptbookVersion
1166
1208
  * TODO: Use here some json-schema, Zod or something similar and change it to:
1167
1209
  * > /**
@@ -2249,113 +2291,35 @@ function assertsExecutionSuccessful(executionResult) {
2249
2291
  */
2250
2292
 
2251
2293
  /**
2252
- * Parses the given script and returns the list of all used variables that are not defined in the script
2253
- *
2254
- * @param script from which to extract the variables
2255
- * @returns the list of variable names
2256
- * @throws {ParseError} if the script is invalid
2257
- * @public exported from `@promptbook/utils`
2258
- */
2259
- function extractVariables(script) {
2260
- var variables = new Set();
2261
- script = "(()=>{".concat(script, "})()");
2262
- try {
2263
- for (var i = 0; i < 100 /* <- TODO: This limit to configuration */; i++)
2264
- try {
2265
- eval(script);
2266
- }
2267
- catch (error) {
2268
- if (!(error instanceof ReferenceError)) {
2269
- throw error;
2270
- }
2271
- var undefinedName = error.message.split(' ')[0];
2272
- /*
2273
- Note: Parsing the error
2274
- [PipelineUrlError: thing is not defined]
2275
- */
2276
- if (!undefinedName) {
2277
- throw error;
2278
- }
2279
- if (script.includes(undefinedName + '(')) {
2280
- script = "const ".concat(undefinedName, " = ()=>'';") + script;
2281
- }
2282
- else {
2283
- variables.add(undefinedName);
2284
- script = "const ".concat(undefinedName, " = '';") + script;
2285
- }
2286
- }
2287
- }
2288
- catch (error) {
2289
- if (!(error instanceof Error)) {
2290
- throw error;
2291
- }
2292
- throw new ParseError(spaceTrim$1(function (block) { return "\n Can not extract variables from the script\n\n ".concat(block(error.toString()), "}\n "); }));
2293
- }
2294
- return variables;
2295
- }
2296
- /**
2297
- * TODO: [🔣] Support for multiple languages - python, java,...
2298
- */
2299
-
2300
- /**
2301
- * Parses the template and returns the set of all used parameters
2294
+ * Determine if the pipeline is fully prepared
2302
2295
  *
2303
- * @param template the template with used parameters
2304
- * @returns the set of parameter names
2305
- * @throws {ParseError} if the script is invalid
2306
- * @public exported from `@promptbook/utils`
2296
+ * @public exported from `@promptbook/core`
2307
2297
  */
2308
- function extractParameterNamesFromTemplate(template) {
2309
- var e_1, _a, e_2, _b, e_3, _c;
2310
- var title = template.title, description = template.description, templateType = template.templateType, content = template.content, preparedContent = template.preparedContent, jokerParameterNames = template.jokerParameterNames;
2311
- var parameterNames = new Set();
2312
- try {
2313
- for (var _d = __values(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(extractParameterNames(title)), false), __read(extractParameterNames(description || '')), false), __read(extractParameterNames(content)), false), __read(extractParameterNames(preparedContent || '')), false)), _e = _d.next(); !_e.done; _e = _d.next()) {
2314
- var parameterName = _e.value;
2315
- parameterNames.add(parameterName);
2316
- }
2317
- }
2318
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
2319
- finally {
2320
- try {
2321
- if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
2322
- }
2323
- finally { if (e_1) throw e_1.error; }
2324
- }
2325
- if (templateType === 'SCRIPT_TEMPLATE') {
2326
- try {
2327
- for (var _f = __values(extractVariables(content)), _g = _f.next(); !_g.done; _g = _f.next()) {
2328
- var parameterName = _g.value;
2329
- parameterNames.add(parameterName);
2330
- }
2331
- }
2332
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
2333
- finally {
2334
- try {
2335
- if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
2336
- }
2337
- finally { if (e_2) throw e_2.error; }
2338
- }
2339
- }
2340
- try {
2341
- for (var _h = __values(jokerParameterNames || []), _j = _h.next(); !_j.done; _j = _h.next()) {
2342
- var jokerName = _j.value;
2343
- parameterNames.add(jokerName);
2344
- }
2298
+ function isPipelinePrepared(pipeline) {
2299
+ // Note: Ignoring `pipeline.preparations` @@@
2300
+ // Note: Ignoring `pipeline.knowledgePieces` @@@
2301
+ if (!pipeline.personas.every(function (persona) { return persona.modelRequirements !== undefined; })) {
2302
+ return false;
2345
2303
  }
2346
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
2347
- finally {
2348
- try {
2349
- if (_j && !_j.done && (_c = _h.return)) _c.call(_h);
2350
- }
2351
- finally { if (e_3) throw e_3.error; }
2304
+ if (!pipeline.knowledgeSources.every(function (knowledgeSource) { return knowledgeSource.preparationIds !== undefined; })) {
2305
+ return false;
2352
2306
  }
2353
- parameterNames.delete('content');
2354
- // <- Note {websiteContent} is used in `preparedContent`
2355
- return parameterNames;
2307
+ /*
2308
+ TODO: [🧠][🍫] `templates` can not be determined if they are fully prepared SO ignoring them
2309
+ > if (!pipeline.templates.every(({ preparedContent }) => preparedContent === undefined)) {
2310
+ > return false;
2311
+ > }
2312
+ */
2313
+ return true;
2356
2314
  }
2357
2315
  /**
2358
- * TODO: [🔣] If script require contentLanguage
2316
+ * TODO: [🔃][main] !!!!! If the pipeline was prepared with different version or different set of models, prepare it once again
2317
+ * TODO: [🐠] Maybe base this on `makeValidator`
2318
+ * TODO: [🧊] Pipeline can be partially prepared, this should return true ONLY if fully prepared
2319
+ * TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
2320
+ * - [🏍] ? Is context in each template
2321
+ * - [♨] Are samples prepared
2322
+ * - [♨] Are templates prepared
2359
2323
  */
2360
2324
 
2361
2325
  /**
@@ -2375,27 +2339,6 @@ function serializeError(error) {
2375
2339
  };
2376
2340
  }
2377
2341
 
2378
- /**
2379
- * Function isValidJsonString will tell you if the string is valid JSON or not
2380
- *
2381
- * @public exported from `@promptbook/utils`
2382
- */
2383
- function isValidJsonString(value /* <- [👨‍⚖️] */) {
2384
- try {
2385
- JSON.parse(value);
2386
- return true;
2387
- }
2388
- catch (error) {
2389
- if (!(error instanceof Error)) {
2390
- throw error;
2391
- }
2392
- if (error.message.includes('Unexpected token')) {
2393
- return false;
2394
- }
2395
- return false;
2396
- }
2397
- }
2398
-
2399
2342
  /**
2400
2343
  * Multiple LLM Execution Tools is a proxy server that uses multiple execution tools internally and exposes the executor interface externally.
2401
2344
  *
@@ -2422,9 +2365,10 @@ var MultipleLlmExecutionTools = /** @class */ (function () {
2422
2365
  });
2423
2366
  Object.defineProperty(MultipleLlmExecutionTools.prototype, "description", {
2424
2367
  get: function () {
2425
- return this.llmExecutionTools
2426
- .map(function (tools, index) { return "".concat(index + 1, ") ").concat(tools.title, " ").concat(tools.description || ''); })
2427
- .join('\n');
2368
+ return this.llmExecutionTools.map(function (_a, index) {
2369
+ var title = _a.title;
2370
+ return "".concat(index + 1, ") `").concat(title, "`");
2371
+ }).join('\n');
2428
2372
  },
2429
2373
  enumerable: false,
2430
2374
  configurable: true
@@ -2622,9 +2566,7 @@ var MultipleLlmExecutionTools = /** @class */ (function () {
2622
2566
  throw new PipelineExecutionError("You have not provided any `LlmExecutionTools`");
2623
2567
  }
2624
2568
  else {
2625
- throw new PipelineExecutionError(spaceTrim(function (block) { return "\n You have not provided any `LlmExecutionTools` that support model variant \"".concat(prompt.modelRequirements.modelVariant, "\n\n Available `LlmExecutionTools`:\n ").concat(block(_this.llmExecutionTools
2626
- .map(function (tools) { return "- ".concat(tools.title, " ").concat(tools.description || ''); })
2627
- .join('\n')), "\n\n "); }));
2569
+ throw new PipelineExecutionError(spaceTrim(function (block) { return "\n You have not provided any `LlmExecutionTools` that support model variant \"".concat(prompt.modelRequirements.modelVariant, "\"\n\n Available `LlmExecutionTools`:\n ").concat(block(_this.description), "\n\n "); }));
2628
2570
  }
2629
2571
  }
2630
2572
  });
@@ -2690,288 +2632,248 @@ function joinLlmExecutionTools() {
2690
2632
  */
2691
2633
 
2692
2634
  /**
2693
- * Extracts all code blocks from markdown.
2635
+ * Takes an item or an array of items and returns an array of items
2694
2636
  *
2695
- * Note: There are multiple simmilar function:
2696
- * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
2697
- * - `extractJsonBlock` extracts exactly one valid JSON code block
2698
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
2699
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
2637
+ * 1) Any item except array and undefined returns array with that one item (also null)
2638
+ * 2) Undefined returns empty array
2639
+ * 3) Array returns itself
2700
2640
  *
2701
- * @param markdown any valid markdown
2702
- * @returns code blocks with language and content
2703
- * @throws {ParseError} if block is not closed properly
2704
- * @public exported from `@promptbook/markdown-utils`
2641
+ * @private internal utility
2705
2642
  */
2706
- function extractAllBlocksFromMarkdown(markdown) {
2707
- var e_1, _a;
2708
- var codeBlocks = [];
2709
- var lines = markdown.split('\n');
2710
- // Note: [0] Ensure that the last block notated by gt > will be closed
2711
- lines.push('');
2712
- var currentCodeBlock = null;
2713
- try {
2714
- for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
2715
- var line = lines_1_1.value;
2716
- if (line.startsWith('> ') || line === '>') {
2717
- if (currentCodeBlock === null) {
2718
- currentCodeBlock = { blockNotation: '>', language: null, content: '' };
2719
- } /* not else */
2720
- if (currentCodeBlock.blockNotation === '>') {
2721
- if (currentCodeBlock.content !== '') {
2722
- currentCodeBlock.content += '\n';
2723
- }
2724
- currentCodeBlock.content += line.slice(2);
2725
- }
2726
- }
2727
- else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '>' /* <- Note: [0] */) {
2728
- codeBlocks.push(currentCodeBlock);
2729
- currentCodeBlock = null;
2730
- }
2731
- /* not else */
2732
- if (line.startsWith('```')) {
2733
- var language = line.slice(3).trim() || null;
2734
- if (currentCodeBlock === null) {
2735
- currentCodeBlock = { blockNotation: '```', language: language, content: '' };
2736
- }
2737
- else {
2738
- if (language !== null) {
2739
- throw new ParseError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed and already opening new ").concat(language, " code block"));
2740
- }
2741
- codeBlocks.push(currentCodeBlock);
2742
- currentCodeBlock = null;
2743
- }
2744
- }
2745
- else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '```') {
2746
- if (currentCodeBlock.content !== '') {
2747
- currentCodeBlock.content += '\n';
2748
- }
2749
- currentCodeBlock.content += line.split('\\`\\`\\`').join('```') /* <- TODO: Maybe make propper unescape */;
2750
- }
2751
- }
2752
- }
2753
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
2754
- finally {
2755
- try {
2756
- if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
2757
- }
2758
- finally { if (e_1) throw e_1.error; }
2643
+ function arrayableToArray(input) {
2644
+ if (input === undefined) {
2645
+ return [];
2759
2646
  }
2760
- if (currentCodeBlock !== null) {
2761
- throw new ParseError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed at the end of the markdown"));
2647
+ if (input instanceof Array) {
2648
+ return input;
2762
2649
  }
2763
- return codeBlocks;
2650
+ return [input];
2764
2651
  }
2765
- /**
2766
- * TODO: Maybe name for `blockNotation` instead of '```' and '>'
2767
- */
2768
2652
 
2769
2653
  /**
2770
- * Extracts extracts exactly one valid JSON code block
2771
- *
2772
- * - When given string is a valid JSON as it is, it just returns it
2773
- * - When there is no JSON code block the function throws a `ParseError`
2774
- * - When there are multiple JSON code blocks the function throws a `ParseError`
2654
+ * @@@
2775
2655
  *
2776
- * Note: It is not important if marked as ```json BUT if it is VALID JSON
2777
- * Note: There are multiple simmilar function:
2778
- * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
2779
- * - `extractJsonBlock` extracts exactly one valid JSON code block
2780
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
2781
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
2782
- *
2783
- * @public exported from `@promptbook/markdown-utils`
2784
- * @throws {ParseError} if there is no valid JSON block in the markdown
2785
- */
2786
- function extractJsonBlock(markdown) {
2787
- if (isValidJsonString(markdown)) {
2788
- return markdown;
2789
- }
2790
- var codeBlocks = extractAllBlocksFromMarkdown(markdown);
2791
- var jsonBlocks = codeBlocks.filter(function (_a) {
2792
- var content = _a.content;
2793
- return isValidJsonString(content);
2794
- });
2795
- if (jsonBlocks.length === 0) {
2796
- throw new Error('There is no valid JSON block in the markdown');
2797
- }
2798
- if (jsonBlocks.length > 1) {
2799
- throw new Error('There are multiple JSON code blocks in the markdown');
2800
- }
2801
- return jsonBlocks[0].content;
2802
- }
2803
- /**
2804
- * TODO: Add some auto-healing logic + extract YAML, JSON5, TOML, etc.
2805
- * TODO: [🏢] Make this logic part of `JsonFormatDefinition` or `isValidJsonString`
2806
- */
2807
-
2808
- /**
2809
- * Determine if the pipeline is fully prepared
2810
- *
2811
- * @public exported from `@promptbook/core`
2656
+ * @public exported from `@promptbook/utils`
2812
2657
  */
2813
- function isPipelinePrepared(pipeline) {
2814
- // Note: Ignoring `pipeline.preparations` @@@
2815
- // Note: Ignoring `pipeline.knowledgePieces` @@@
2816
- if (!pipeline.personas.every(function (persona) { return persona.modelRequirements !== undefined; })) {
2817
- return false;
2818
- }
2819
- if (!pipeline.knowledgeSources.every(function (knowledgeSource) { return knowledgeSource.preparationIds !== undefined; })) {
2820
- return false;
2821
- }
2658
+ function deepClone(objectValue) {
2659
+ return JSON.parse(JSON.stringify(objectValue));
2822
2660
  /*
2823
- TODO: [🧠][🍫] `templates` can not be determined if they are fully prepared SO ignoring them
2824
- > if (!pipeline.templates.every(({ preparedContent }) => preparedContent === undefined)) {
2825
- > return false;
2661
+ TODO: [🧠] Is there a better implementation?
2662
+ > const propertyNames = Object.getOwnPropertyNames(objectValue);
2663
+ > for (const propertyName of propertyNames) {
2664
+ > const value = (objectValue as really_any)[propertyName];
2665
+ > if (value && typeof value === 'object') {
2666
+ > deepClone(value);
2667
+ > }
2826
2668
  > }
2669
+ > return Object.assign({}, objectValue);
2827
2670
  */
2828
- return true;
2829
2671
  }
2830
2672
  /**
2831
- * TODO: [🔃][main] !!!!! If the pipeline was prepared with different version or different set of models, prepare it once again
2832
- * TODO: [🐠] Maybe base this on `makeValidator`
2833
- * TODO: [🧊] Pipeline can be partially prepared, this should return true ONLY if fully prepared
2834
- * TODO: [🧿] Maybe do same process with same granularity and subfinctions as `preparePipeline`
2835
- * - [🏍] ? Is context in each template
2836
- * - [♨] Are samples prepared
2837
- * - [♨] Are templates prepared
2673
+ * TODO: [🧠] Is there a way how to meaningfully test this utility
2838
2674
  */
2839
2675
 
2840
2676
  /**
2841
- * Takes an item or an array of items and returns an array of items
2677
+ * Function `addUsage` will add multiple usages into one
2842
2678
  *
2843
- * 1) Any item except array and undefined returns array with that one item (also null)
2844
- * 2) Undefined returns empty array
2845
- * 3) Array returns itself
2679
+ * Note: If you provide 0 values, it returns ZERO_USAGE
2846
2680
  *
2847
- * @private internal utility
2681
+ * @public exported from `@promptbook/core`
2848
2682
  */
2849
- function arrayableToArray(input) {
2850
- if (input === undefined) {
2851
- return [];
2852
- }
2853
- if (input instanceof Array) {
2854
- return input;
2683
+ function addUsage() {
2684
+ var usageItems = [];
2685
+ for (var _i = 0; _i < arguments.length; _i++) {
2686
+ usageItems[_i] = arguments[_i];
2855
2687
  }
2856
- return [input];
2688
+ return usageItems.reduce(function (acc, item) {
2689
+ var e_1, _a, e_2, _b;
2690
+ var _c;
2691
+ acc.price.value += ((_c = item.price) === null || _c === void 0 ? void 0 : _c.value) || 0;
2692
+ try {
2693
+ for (var _d = __values(Object.keys(acc.input)), _e = _d.next(); !_e.done; _e = _d.next()) {
2694
+ var key = _e.value;
2695
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2696
+ //@ts-ignore
2697
+ if (item.input[key]) {
2698
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2699
+ //@ts-ignore
2700
+ acc.input[key].value += item.input[key].value || 0;
2701
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2702
+ //@ts-ignore
2703
+ if (item.input[key].isUncertain) {
2704
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2705
+ //@ts-ignore
2706
+ acc.input[key].isUncertain = true;
2707
+ }
2708
+ }
2709
+ }
2710
+ }
2711
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
2712
+ finally {
2713
+ try {
2714
+ if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
2715
+ }
2716
+ finally { if (e_1) throw e_1.error; }
2717
+ }
2718
+ try {
2719
+ for (var _f = __values(Object.keys(acc.output)), _g = _f.next(); !_g.done; _g = _f.next()) {
2720
+ var key = _g.value;
2721
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2722
+ //@ts-ignore
2723
+ if (item.output[key]) {
2724
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2725
+ //@ts-ignore
2726
+ acc.output[key].value += item.output[key].value || 0;
2727
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2728
+ //@ts-ignore
2729
+ if (item.output[key].isUncertain) {
2730
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2731
+ //@ts-ignore
2732
+ acc.output[key].isUncertain = true;
2733
+ }
2734
+ }
2735
+ }
2736
+ }
2737
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
2738
+ finally {
2739
+ try {
2740
+ if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
2741
+ }
2742
+ finally { if (e_2) throw e_2.error; }
2743
+ }
2744
+ return acc;
2745
+ }, deepClone(ZERO_USAGE));
2857
2746
  }
2858
2747
 
2859
2748
  /**
2860
- * Just says that the variable is not used but should be kept
2861
- * No side effects.
2862
- *
2863
- * Note: It can be usefull for:
2864
- *
2865
- * 1) Suppressing eager optimization of unused imports
2866
- * 2) Suppressing eslint errors of unused variables in the tests
2867
- * 3) Keeping the type of the variable for type testing
2749
+ * Parses the given script and returns the list of all used variables that are not defined in the script
2868
2750
  *
2869
- * @param value any values
2870
- * @returns void
2871
- * @private within the repository
2751
+ * @param script from which to extract the variables
2752
+ * @returns the list of variable names
2753
+ * @throws {ParseError} if the script is invalid
2754
+ * @public exported from `@promptbook/utils`
2872
2755
  */
2873
- function keepUnused() {
2874
- var valuesToKeep = [];
2875
- for (var _i = 0; _i < arguments.length; _i++) {
2876
- valuesToKeep[_i] = arguments[_i];
2756
+ function extractVariables(script) {
2757
+ var variables = new Set();
2758
+ script = "(()=>{".concat(script, "})()");
2759
+ try {
2760
+ for (var i = 0; i < 100 /* <- TODO: This limit to configuration */; i++)
2761
+ try {
2762
+ eval(script);
2763
+ }
2764
+ catch (error) {
2765
+ if (!(error instanceof ReferenceError)) {
2766
+ throw error;
2767
+ }
2768
+ var undefinedName = error.message.split(' ')[0];
2769
+ /*
2770
+ Note: Parsing the error
2771
+ [PipelineUrlError: thing is not defined]
2772
+ */
2773
+ if (!undefinedName) {
2774
+ throw error;
2775
+ }
2776
+ if (script.includes(undefinedName + '(')) {
2777
+ script = "const ".concat(undefinedName, " = ()=>'';") + script;
2778
+ }
2779
+ else {
2780
+ variables.add(undefinedName);
2781
+ script = "const ".concat(undefinedName, " = '';") + script;
2782
+ }
2783
+ }
2784
+ }
2785
+ catch (error) {
2786
+ if (!(error instanceof Error)) {
2787
+ throw error;
2788
+ }
2789
+ throw new ParseError(spaceTrim$1(function (block) { return "\n Can not extract variables from the script\n\n ".concat(block(error.toString()), "}\n "); }));
2877
2790
  }
2791
+ return variables;
2878
2792
  }
2879
-
2880
2793
  /**
2881
- * Just marks a place of place where should be something implemented
2882
- * No side effects.
2883
- *
2884
- * Note: It can be usefull suppressing eslint errors of unused variables
2885
- *
2886
- * @param value any values
2887
- * @returns void
2888
- * @private within the repository
2794
+ * TODO: [🔣] Support for multiple languages - python, java,...
2889
2795
  */
2890
- function TODO_USE() {
2891
- var value = [];
2892
- for (var _i = 0; _i < arguments.length; _i++) {
2893
- value[_i] = arguments[_i];
2894
- }
2895
- }
2896
2796
 
2897
2797
  /**
2898
- * Replaces parameters in template with values from parameters object
2798
+ * Parses the template and returns the set of all used parameters
2899
2799
  *
2900
- * @param template the template with parameters in {curly} braces
2901
- * @param parameters the object with parameters
2902
- * @returns the template with replaced parameters
2903
- * @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
2800
+ * @param template the template with used parameters
2801
+ * @returns the set of parameter names
2802
+ * @throws {ParseError} if the script is invalid
2904
2803
  * @public exported from `@promptbook/utils`
2905
2804
  */
2906
- function replaceParameters(template, parameters) {
2907
- var e_1, _a;
2805
+ function extractParameterNamesFromTemplate(template) {
2806
+ var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
2807
+ var title = template.title, description = template.description, templateType = template.templateType, content = template.content, preparedContent = template.preparedContent, jokerParameterNames = template.jokerParameterNames, foreach = template.foreach;
2808
+ var parameterNames = new Set();
2908
2809
  try {
2909
- for (var _b = __values(Object.entries(parameters)), _c = _b.next(); !_c.done; _c = _b.next()) {
2910
- var _d = __read(_c.value, 2), parameterName = _d[0], parameterValue = _d[1];
2911
- if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
2912
- throw new UnexpectedError("Parameter {".concat(parameterName, "} has missing value"));
2913
- }
2914
- else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
2915
- // TODO: [🍵]
2916
- throw new UnexpectedError("Parameter {".concat(parameterName, "} is restricted to use"));
2917
- }
2810
+ for (var _e = __values(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(extractParameterNames(title)), false), __read(extractParameterNames(description || '')), false), __read(extractParameterNames(content)), false), __read(extractParameterNames(preparedContent || '')), false)), _f = _e.next(); !_f.done; _f = _e.next()) {
2811
+ var parameterName = _f.value;
2812
+ parameterNames.add(parameterName);
2918
2813
  }
2919
2814
  }
2920
2815
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
2921
2816
  finally {
2922
2817
  try {
2923
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2818
+ if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
2924
2819
  }
2925
2820
  finally { if (e_1) throw e_1.error; }
2926
2821
  }
2927
- var replacedTemplate = template;
2928
- var match;
2929
- var loopLimit = LOOP_LIMIT;
2930
- var _loop_1 = function () {
2931
- if (loopLimit-- < 0) {
2932
- throw new LimitReachedError('Loop limit reached during parameters replacement in `replaceParameters`');
2933
- }
2934
- var precol = match.groups.precol;
2935
- var parameterName = match.groups.parameterName;
2936
- if (parameterName === '') {
2937
- return "continue";
2822
+ if (templateType === 'SCRIPT_TEMPLATE') {
2823
+ try {
2824
+ for (var _g = __values(extractVariables(content)), _h = _g.next(); !_h.done; _h = _g.next()) {
2825
+ var parameterName = _h.value;
2826
+ parameterNames.add(parameterName);
2827
+ }
2938
2828
  }
2939
- if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
2940
- throw new PipelineExecutionError('Parameter is already opened or not closed');
2829
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
2830
+ finally {
2831
+ try {
2832
+ if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
2833
+ }
2834
+ finally { if (e_2) throw e_2.error; }
2941
2835
  }
2942
- if (parameters[parameterName] === undefined) {
2943
- throw new PipelineExecutionError("Parameter {".concat(parameterName, "} is not defined"));
2944
- }
2945
- var parameterValue = parameters[parameterName];
2946
- if (parameterValue === undefined) {
2947
- throw new PipelineExecutionError("Parameter {".concat(parameterName, "} is not defined"));
2948
- }
2949
- parameterValue = parameterValue.toString();
2950
- if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
2951
- parameterValue = parameterValue
2952
- .split('\n')
2953
- .map(function (line, index) { return (index === 0 ? line : "".concat(precol).concat(line)); })
2954
- .join('\n');
2836
+ }
2837
+ try {
2838
+ for (var _j = __values(jokerParameterNames || []), _k = _j.next(); !_k.done; _k = _j.next()) {
2839
+ var jokerName = _k.value;
2840
+ parameterNames.add(jokerName);
2955
2841
  }
2956
- replacedTemplate =
2957
- replacedTemplate.substring(0, match.index + precol.length) +
2958
- parameterValue +
2959
- replacedTemplate.substring(match.index + precol.length + parameterName.length + 2);
2960
- };
2961
- while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
2962
- .exec(replacedTemplate))) {
2963
- _loop_1();
2964
2842
  }
2965
- // [💫] Check if there are parameters that are not closed properly
2966
- if (/{\w+$/.test(replacedTemplate)) {
2967
- throw new PipelineExecutionError('Parameter is not closed');
2843
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
2844
+ finally {
2845
+ try {
2846
+ if (_k && !_k.done && (_c = _j.return)) _c.call(_j);
2847
+ }
2848
+ finally { if (e_3) throw e_3.error; }
2968
2849
  }
2969
- // [💫] Check if there are parameters that are not opened properly
2970
- if (/^\w+}/.test(replacedTemplate)) {
2971
- throw new PipelineExecutionError('Parameter is not opened');
2850
+ parameterNames.delete('content');
2851
+ // <- Note {websiteContent} is used in `preparedContent`
2852
+ // Note: [🍭] Fixing dependent subparameterName from FOREACH command
2853
+ if (foreach !== undefined) {
2854
+ try {
2855
+ for (var _l = __values(foreach.subparameterNames), _m = _l.next(); !_m.done; _m = _l.next()) {
2856
+ var subparameterName = _m.value;
2857
+ if (parameterNames.has(subparameterName)) {
2858
+ parameterNames.delete(subparameterName);
2859
+ parameterNames.add(foreach.parameterName);
2860
+ // <- TODO: [🚎] Warn/logic error when `subparameterName` not used
2861
+ }
2862
+ }
2863
+ }
2864
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
2865
+ finally {
2866
+ try {
2867
+ if (_m && !_m.done && (_d = _l.return)) _d.call(_l);
2868
+ }
2869
+ finally { if (e_4) throw e_4.error; }
2870
+ }
2972
2871
  }
2973
- return replacedTemplate;
2872
+ return parameterNames;
2974
2873
  }
2874
+ /**
2875
+ * TODO: [🔣] If script require contentLanguage
2876
+ */
2975
2877
 
2976
2878
  /**
2977
2879
  * Create difference set of two sets.
@@ -3049,212 +2951,351 @@ function union() {
3049
2951
  }
3050
2952
 
3051
2953
  /**
3052
- * @@@
2954
+ * Just marks a place of place where should be something implemented
2955
+ * No side effects.
3053
2956
  *
3054
- * @public exported from `@promptbook/utils`
2957
+ * Note: It can be usefull suppressing eslint errors of unused variables
2958
+ *
2959
+ * @param value any values
2960
+ * @returns void
2961
+ * @private within the repository
3055
2962
  */
3056
- function deepClone(objectValue) {
3057
- return JSON.parse(JSON.stringify(objectValue));
3058
- /*
3059
- TODO: [🧠] Is there a better implementation?
3060
- > const propertyNames = Object.getOwnPropertyNames(objectValue);
3061
- > for (const propertyName of propertyNames) {
3062
- > const value = (objectValue as really_any)[propertyName];
3063
- > if (value && typeof value === 'object') {
3064
- > deepClone(value);
3065
- > }
3066
- > }
3067
- > return Object.assign({}, objectValue);
3068
- */
2963
+ function TODO_USE() {
2964
+ var value = [];
2965
+ for (var _i = 0; _i < arguments.length; _i++) {
2966
+ value[_i] = arguments[_i];
2967
+ }
3069
2968
  }
3070
- /**
3071
- * TODO: [🧠] Is there a way how to meaningfully test this utility
3072
- */
3073
2969
 
3074
2970
  /**
3075
- * Function `addUsage` will add multiple usages into one
3076
- *
3077
- * Note: If you provide 0 values, it returns ZERO_USAGE
2971
+ * @@@
3078
2972
  *
3079
2973
  * @public exported from `@promptbook/core`
3080
2974
  */
3081
- function addUsage() {
3082
- var usageItems = [];
3083
- for (var _i = 0; _i < arguments.length; _i++) {
3084
- usageItems[_i] = arguments[_i];
3085
- }
3086
- return usageItems.reduce(function (acc, item) {
3087
- var e_1, _a, e_2, _b;
3088
- var _c;
3089
- acc.price.value += ((_c = item.price) === null || _c === void 0 ? void 0 : _c.value) || 0;
3090
- try {
3091
- for (var _d = __values(Object.keys(acc.input)), _e = _d.next(); !_e.done; _e = _d.next()) {
3092
- var key = _e.value;
3093
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3094
- //@ts-ignore
3095
- if (item.input[key]) {
3096
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3097
- //@ts-ignore
3098
- acc.input[key].value += item.input[key].value || 0;
3099
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3100
- //@ts-ignore
3101
- if (item.input[key].isUncertain) {
3102
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3103
- //@ts-ignore
3104
- acc.input[key].isUncertain = true;
3105
- }
3106
- }
3107
- }
3108
- }
3109
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
3110
- finally {
3111
- try {
3112
- if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
3113
- }
3114
- finally { if (e_1) throw e_1.error; }
3115
- }
3116
- try {
3117
- for (var _f = __values(Object.keys(acc.output)), _g = _f.next(); !_g.done; _g = _f.next()) {
3118
- var key = _g.value;
3119
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3120
- //@ts-ignore
3121
- if (item.output[key]) {
3122
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3123
- //@ts-ignore
3124
- acc.output[key].value += item.output[key].value || 0;
3125
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3126
- //@ts-ignore
3127
- if (item.output[key].isUncertain) {
3128
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3129
- //@ts-ignore
3130
- acc.output[key].isUncertain = true;
3131
- }
3132
- }
3133
- }
3134
- }
3135
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
3136
- finally {
3137
- try {
3138
- if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
3139
- }
3140
- finally { if (e_2) throw e_2.error; }
3141
- }
3142
- return acc;
3143
- }, deepClone(ZERO_USAGE));
3144
- }
2975
+ var MANDATORY_CSV_SETTINGS = Object.freeze({
2976
+ header: true,
2977
+ // encoding: 'utf8',
2978
+ });
3145
2979
 
3146
2980
  /**
3147
- * Counts number of characters in the text
2981
+ * Definition for CSV spreadsheet
3148
2982
  *
3149
- * @public exported from `@promptbook/utils`
2983
+ * @public exported from `@promptbook/core`
2984
+ * <- TODO: [🏢] Export from package `@promptbook/csv`
2985
+ */
2986
+ var CsvFormatDefinition = {
2987
+ formatName: 'CSV',
2988
+ aliases: ['SPREADSHEET', 'TABLE'],
2989
+ isValid: function (value, settings, schema) {
2990
+ // TODO: !!!!!! Implement CSV validation
2991
+ TODO_USE(value /* <- TODO: Use value here */);
2992
+ TODO_USE(settings /* <- TODO: Use settings here */);
2993
+ TODO_USE(schema /* <- TODO: Use schema here */);
2994
+ return true;
2995
+ },
2996
+ canBeValid: function (partialValue, settings, schema) {
2997
+ TODO_USE(partialValue /* <- TODO: Use partialValue here */);
2998
+ TODO_USE(settings /* <- TODO: Use settings here */);
2999
+ TODO_USE(schema /* <- TODO: Use schema here */);
3000
+ return true;
3001
+ },
3002
+ heal: function (value, settings, schema) {
3003
+ TODO_USE(value /* <- TODO: Use partialValue here */);
3004
+ TODO_USE(settings /* <- TODO: Use settings here */);
3005
+ TODO_USE(schema /* <- TODO: Use schema here */);
3006
+ throw new Error('Not implemented');
3007
+ },
3008
+ subvalueDefinitions: [
3009
+ {
3010
+ subvalueName: 'ROW',
3011
+ mapValues: function (value, settings, mapCallback) {
3012
+ return __awaiter(this, void 0, void 0, function () {
3013
+ var csv, mappedData;
3014
+ var _this = this;
3015
+ return __generator(this, function (_a) {
3016
+ switch (_a.label) {
3017
+ case 0:
3018
+ csv = parse(value, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS));
3019
+ if (csv.errors.length !== 0) {
3020
+ throw new ParseError(// <- TODO: !!!!!! Split PipelineParseError and FormatParseError -> CsvParseError
3021
+ spaceTrim(function (block) { return "\n CSV parsing error\n\n ".concat(block(csv.errors.map(function (error) { return error.message; }).join('\n\n')), "\n "); }));
3022
+ }
3023
+ return [4 /*yield*/, Promise.all(csv.data.map(function (row, index) { return __awaiter(_this, void 0, void 0, function () {
3024
+ var _a;
3025
+ var _b;
3026
+ return __generator(this, function (_c) {
3027
+ switch (_c.label) {
3028
+ case 0:
3029
+ _a = [__assign({}, row)];
3030
+ _b = {};
3031
+ // <- TODO: !!!!!! Dynamic new column name and position
3032
+ // <- TODO: !!!!!! Check name collisions
3033
+ return [4 /*yield*/, mapCallback(row, index)];
3034
+ case 1: return [2 /*return*/, (__assign.apply(void 0, _a.concat([(_b.newColumn =
3035
+ // <- TODO: !!!!!! Dynamic new column name and position
3036
+ // <- TODO: !!!!!! Check name collisions
3037
+ _c.sent(), _b)])))];
3038
+ }
3039
+ });
3040
+ }); }))];
3041
+ case 1:
3042
+ mappedData = _a.sent();
3043
+ return [2 /*return*/, unparse(mappedData, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS))];
3044
+ }
3045
+ });
3046
+ });
3047
+ },
3048
+ },
3049
+ {
3050
+ subvalueName: 'CELL',
3051
+ mapValues: function (value, settings, mapCallback) {
3052
+ return __awaiter(this, void 0, void 0, function () {
3053
+ var csv, mappedData;
3054
+ var _this = this;
3055
+ return __generator(this, function (_a) {
3056
+ switch (_a.label) {
3057
+ case 0:
3058
+ csv = parse(value, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS));
3059
+ if (csv.errors.length !== 0) {
3060
+ throw new ParseError(// <- TODO: !!!!!! Split PipelineParseError and FormatParseError -> CsvParseError
3061
+ spaceTrim(function (block) { return "\n CSV parsing error\n\n ".concat(block(csv.errors.map(function (error) { return error.message; }).join('\n\n')), "\n "); }));
3062
+ }
3063
+ return [4 /*yield*/, Promise.all(csv.data.map(function (row, rowIndex) { return __awaiter(_this, void 0, void 0, function () {
3064
+ var _this = this;
3065
+ return __generator(this, function (_a) {
3066
+ return [2 /*return*/, /* not await */ Promise.all(Object.entries(row).map(function (_a, columnIndex) {
3067
+ var _b = __read(_a, 2), key = _b[0], value = _b[1];
3068
+ return __awaiter(_this, void 0, void 0, function () {
3069
+ var index;
3070
+ var _c;
3071
+ return __generator(this, function (_d) {
3072
+ index = rowIndex * Object.keys(row).length + columnIndex;
3073
+ return [2 /*return*/, /* not await */ mapCallback((_c = {}, _c[key] = value, _c), index)];
3074
+ });
3075
+ });
3076
+ }))];
3077
+ });
3078
+ }); }))];
3079
+ case 1:
3080
+ mappedData = _a.sent();
3081
+ return [2 /*return*/, unparse(mappedData, __assign(__assign({}, settings), MANDATORY_CSV_SETTINGS))];
3082
+ }
3083
+ });
3084
+ });
3085
+ },
3086
+ },
3087
+ ],
3088
+ };
3089
+ /**
3090
+ * TODO: [🍓] In `CsvFormatDefinition` implement simple `isValid`
3091
+ * TODO: [🍓] In `CsvFormatDefinition` implement partial `canBeValid`
3092
+ * TODO: [🍓] In `CsvFormatDefinition` implement `heal
3093
+ * TODO: [🍓] In `CsvFormatDefinition` implement `subvalueDefinitions`
3094
+ * TODO: [🏢] Allow to expect something inside CSV objects and other formats
3150
3095
  */
3151
- function countCharacters(text) {
3152
- // Remove null characters
3153
- text = text.replace(/\0/g, '');
3154
- // Replace emojis (and also ZWJ sequence) with hyphens
3155
- text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
3156
- text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
3157
- text = text.replace(/\p{Extended_Pictographic}(\u{200D}\p{Extended_Pictographic})*/gu, '-');
3158
- return text.length;
3159
- }
3160
3096
 
3161
3097
  /**
3162
- * Counts number of lines in the text
3098
+ * Function isValidJsonString will tell you if the string is valid JSON or not
3163
3099
  *
3164
3100
  * @public exported from `@promptbook/utils`
3165
3101
  */
3166
- function countLines(text) {
3167
- if (text === '') {
3168
- return 0;
3102
+ function isValidJsonString(value /* <- [👨‍⚖️] */) {
3103
+ try {
3104
+ JSON.parse(value);
3105
+ return true;
3106
+ }
3107
+ catch (error) {
3108
+ if (!(error instanceof Error)) {
3109
+ throw error;
3110
+ }
3111
+ if (error.message.includes('Unexpected token')) {
3112
+ return false;
3113
+ }
3114
+ return false;
3169
3115
  }
3170
- return text.split('\n').length;
3171
3116
  }
3172
3117
 
3173
3118
  /**
3174
- * Counts number of pages in the text
3119
+ * Definition for JSON format
3175
3120
  *
3176
- * @public exported from `@promptbook/utils`
3121
+ * @private still in development [🏢]
3177
3122
  */
3178
- function countPages(text) {
3179
- var sentencesPerPage = 5; // Assuming each page has 5 sentences
3180
- var sentences = text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
3181
- var pageCount = Math.ceil(sentences.length / sentencesPerPage);
3182
- return pageCount;
3183
- }
3184
-
3123
+ var JsonFormatDefinition = {
3124
+ formatName: 'JSON',
3125
+ mimeType: 'application/json',
3126
+ isValid: function (value, settings, schema) {
3127
+ TODO_USE(schema /* <- TODO: Use schema here */);
3128
+ TODO_USE(settings /* <- TODO: Use settings here */);
3129
+ return isValidJsonString(value);
3130
+ },
3131
+ canBeValid: function (partialValue, settings, schema) {
3132
+ TODO_USE(partialValue /* <- TODO: Use partialValue here */);
3133
+ TODO_USE(settings /* <- TODO: Use settings here */);
3134
+ TODO_USE(schema /* <- TODO: Use schema here */);
3135
+ return true;
3136
+ },
3137
+ heal: function (value, settings, schema) {
3138
+ TODO_USE(value /* <- TODO: Use partialValue here */);
3139
+ TODO_USE(settings /* <- TODO: Use settings here */);
3140
+ TODO_USE(schema /* <- TODO: Use schema here */);
3141
+ throw new Error('Not implemented');
3142
+ },
3143
+ subvalueDefinitions: [],
3144
+ };
3185
3145
  /**
3186
- * Counts number of paragraphs in the text
3187
- *
3188
- * @public exported from `@promptbook/utils`
3146
+ * TODO: [🧠] Maybe propper instance of object
3147
+ * TODO: [0] Make string_serialized_json
3148
+ * TODO: [1] Make type for JSON Settings and Schema
3149
+ * TODO: [🧠] What to use for validating JSONs - JSON Schema, ZoD, typescript types/interfaces,...?
3150
+ * TODO: [🍓] In `JsonFormatDefinition` implement simple `isValid`
3151
+ * TODO: [🍓] In `JsonFormatDefinition` implement partial `canBeValid`
3152
+ * TODO: [🍓] In `JsonFormatDefinition` implement `heal
3153
+ * TODO: [🍓] In `JsonFormatDefinition` implement `subvalueDefinitions`
3154
+ * TODO: [🏢] Allow to expect something inside JSON objects and other formats
3189
3155
  */
3190
- function countParagraphs(text) {
3191
- return text.split(/\n\s*\n/).filter(function (paragraph) { return paragraph.trim() !== ''; }).length;
3192
- }
3193
3156
 
3194
3157
  /**
3195
- * Split text into sentences
3158
+ * Definition for any text - this will be always valid
3196
3159
  *
3197
- * @public exported from `@promptbook/utils`
3160
+ * Note: This is not useful for validation, but for splitting and mapping with `subvalueDefinitions`
3161
+ *
3162
+ * @public exported from `@promptbook/core`
3198
3163
  */
3199
- function splitIntoSentences(text) {
3200
- return text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
3201
- }
3164
+ var TextFormatDefinition = {
3165
+ formatName: 'TEXT',
3166
+ isValid: function (value) {
3167
+ return typeof value === 'string';
3168
+ },
3169
+ canBeValid: function (partialValue) {
3170
+ return typeof partialValue === 'string';
3171
+ },
3172
+ heal: function () {
3173
+ throw new UnexpectedError('It does not make sense to call `TextFormatDefinition.heal`');
3174
+ },
3175
+ subvalueDefinitions: [
3176
+ {
3177
+ subvalueName: 'LINE',
3178
+ mapValues: function (value, settings, mapCallback) {
3179
+ return __awaiter(this, void 0, void 0, function () {
3180
+ var lines, mappedLines;
3181
+ return __generator(this, function (_a) {
3182
+ switch (_a.label) {
3183
+ case 0:
3184
+ lines = value.split('\n');
3185
+ return [4 /*yield*/, Promise.all(lines.map(function (lineContent, lineNumber) {
3186
+ // TODO: [🧠] Maybe option to skip empty line
3187
+ /* not await */ return mapCallback({
3188
+ lineContent: lineContent,
3189
+ // TODO: [🧠] Maybe also put here `lineNumber`
3190
+ }, lineNumber);
3191
+ }))];
3192
+ case 1:
3193
+ mappedLines = _a.sent();
3194
+ return [2 /*return*/, mappedLines.join('\n')];
3195
+ }
3196
+ });
3197
+ });
3198
+ },
3199
+ },
3200
+ // <- TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
3201
+ ],
3202
+ };
3202
3203
  /**
3203
- * Counts number of sentences in the text
3204
- *
3205
- * @public exported from `@promptbook/utils`
3204
+ * TODO: [1] Make type for XML Text and Schema
3205
+ * TODO: [🧠][🤠] Here should be all words, characters, lines, paragraphs, pages aviable as subvalues
3206
+ * TODO: [🍓] In `TextFormatDefinition` implement simple `isValid`
3207
+ * TODO: [🍓] In `TextFormatDefinition` implement partial `canBeValid`
3208
+ * TODO: [🍓] In `TextFormatDefinition` implement `heal
3209
+ * TODO: [🍓] In `TextFormatDefinition` implement `subvalueDefinitions`
3210
+ * TODO: [🏢] Allow to expect something inside each item of list and other formats
3206
3211
  */
3207
- function countSentences(text) {
3208
- return splitIntoSentences(text).length;
3209
- }
3210
3212
 
3211
3213
  /**
3212
- * Counts number of words in the text
3214
+ * Definition for XML format
3213
3215
  *
3214
- * @public exported from `@promptbook/utils`
3216
+ * @private still in development [🏢]
3217
+ */
3218
+ var XmlFormatDefinition = {
3219
+ formatName: 'XML',
3220
+ mimeType: 'application/xml',
3221
+ isValid: function (value, settings, schema) {
3222
+ TODO_USE(value /* <- TODO: Use value here */);
3223
+ TODO_USE(settings /* <- TODO: Use settings here */);
3224
+ TODO_USE(schema /* <- TODO: Use schema here */);
3225
+ return true;
3226
+ },
3227
+ canBeValid: function (partialValue, settings, schema) {
3228
+ TODO_USE(partialValue /* <- TODO: Use partialValue here */);
3229
+ TODO_USE(settings /* <- TODO: Use settings here */);
3230
+ TODO_USE(schema /* <- TODO: Use schema here */);
3231
+ return true;
3232
+ },
3233
+ heal: function (value, settings, schema) {
3234
+ TODO_USE(value /* <- TODO: Use partialValue here */);
3235
+ TODO_USE(settings /* <- TODO: Use settings here */);
3236
+ TODO_USE(schema /* <- TODO: Use schema here */);
3237
+ throw new Error('Not implemented');
3238
+ },
3239
+ subvalueDefinitions: [],
3240
+ };
3241
+ /**
3242
+ * TODO: [🧠] Maybe propper instance of object
3243
+ * TODO: [0] Make string_serialized_xml
3244
+ * TODO: [1] Make type for XML Settings and Schema
3245
+ * TODO: [🧠] What to use for validating XMLs - XSD,...
3246
+ * TODO: [🍓] In `XmlFormatDefinition` implement simple `isValid`
3247
+ * TODO: [🍓] In `XmlFormatDefinition` implement partial `canBeValid`
3248
+ * TODO: [🍓] In `XmlFormatDefinition` implement `heal
3249
+ * TODO: [🍓] In `XmlFormatDefinition` implement `subvalueDefinitions`
3250
+ * TODO: [🏢] Allow to expect something inside XML and other formats
3215
3251
  */
3216
- function countWords(text) {
3217
- text = text.replace(/[\p{Extended_Pictographic}]/gu, 'a');
3218
- text = removeDiacritics(text);
3219
- return text.split(/[^a-zа-я0-9]+/i).filter(function (word) { return word.length > 0; }).length;
3220
- }
3221
3252
 
3222
3253
  /**
3223
- * Index of all counter functions
3254
+ * Definitions for all formats supported by Promptbook
3224
3255
  *
3225
- * @public exported from `@promptbook/utils`
3256
+ * @private internal index of `...` <- TODO [🏢]
3226
3257
  */
3227
- var CountUtils = {
3228
- CHARACTERS: countCharacters,
3229
- WORDS: countWords,
3230
- SENTENCES: countSentences,
3231
- PARAGRAPHS: countParagraphs,
3232
- LINES: countLines,
3233
- PAGES: countPages,
3234
- };
3258
+ var FORMAT_DEFINITIONS = [
3259
+ JsonFormatDefinition,
3260
+ XmlFormatDefinition,
3261
+ TextFormatDefinition,
3262
+ CsvFormatDefinition,
3263
+ ];
3235
3264
 
3236
3265
  /**
3237
- * Function checkExpectations will check if the expectations on given value are met
3266
+ * Maps available parameters to expected parameters
3238
3267
  *
3239
- * Note: There are two simmilar functions:
3240
- * - `checkExpectations` which throws an error if the expectations are not met
3241
- * - `isPassingExpectations` which returns a boolean
3268
+ * The strategy is:
3269
+ * 1) @@@
3270
+ * 2) @@@
3242
3271
  *
3243
- * @throws {ExpectError} if the expectations are not met
3244
- * @returns {void} Nothing
3245
- * @private internal function of `createPipelineExecutor`
3272
+ * @throws {PipelineExecutionError} @@@
3273
+ * @private within the repository used in `createPipelineExecutor`
3246
3274
  */
3247
- function checkExpectations(expectations, value) {
3275
+ function mapAvailableToExpectedParameters(options) {
3248
3276
  var e_1, _a;
3277
+ var expectedParameters = options.expectedParameters, availableParameters = options.availableParameters;
3278
+ var availableParametersNames = new Set(Object.keys(availableParameters));
3279
+ var expectedParameterNames = new Set(Object.keys(expectedParameters));
3280
+ var mappedParameters = {};
3249
3281
  try {
3250
- for (var _b = __values(Object.entries(expectations)), _c = _b.next(); !_c.done; _c = _b.next()) {
3251
- var _d = __read(_c.value, 2), unit = _d[0], _e = _d[1], max = _e.max, min = _e.min;
3252
- var amount = CountUtils[unit.toUpperCase()](value);
3253
- if (min && amount < min) {
3254
- throw new ExpectError("Expected at least ".concat(min, " ").concat(unit, " but got ").concat(amount));
3255
- } /* not else */
3256
- if (max && amount > max) {
3257
- throw new ExpectError("Expected at most ".concat(max, " ").concat(unit, " but got ").concat(amount));
3282
+ // Phase 1️⃣: Matching mapping
3283
+ for (var _b = __values(Array.from(union(availableParametersNames, expectedParameterNames))), _c = _b.next(); !_c.done; _c = _b.next()) {
3284
+ var parameterName = _c.value;
3285
+ // Situation: Parameter is available and expected
3286
+ if (availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
3287
+ mappedParameters[parameterName] = availableParameters[parameterName];
3288
+ // <- Note: [👩‍👩‍👧] Maybe detect parameter collision here?
3289
+ availableParametersNames.delete(parameterName);
3290
+ expectedParameterNames.delete(parameterName);
3291
+ }
3292
+ // Situation: Parameter is available but NOT expected
3293
+ else if (availableParametersNames.has(parameterName) && !expectedParameterNames.has(parameterName)) {
3294
+ // [🐱‍👤] Do not pass this parameter to prompt - Maybe use it non-matching mapping
3295
+ }
3296
+ // Situation: Parameter is NOT available BUT expected
3297
+ else if (!availableParametersNames.has(parameterName) && expectedParameterNames.has(parameterName)) {
3298
+ // Do nothing here - this will be maybe fixed in the non-matching mapping
3258
3299
  }
3259
3300
  }
3260
3301
  }
@@ -3265,622 +3306,1139 @@ function checkExpectations(expectations, value) {
3265
3306
  }
3266
3307
  finally { if (e_1) throw e_1.error; }
3267
3308
  }
3309
+ if (expectedParameterNames.size === 0) {
3310
+ // Note: [👨‍👨‍👧] Now we can freeze `mappedParameters` to prevent @@@
3311
+ Object.freeze(mappedParameters);
3312
+ return mappedParameters;
3313
+ }
3314
+ // Phase 2️⃣: Non-matching mapping
3315
+ if (expectedParameterNames.size !== availableParametersNames.size) {
3316
+ throw new PipelineExecutionError(spaceTrim(function (block) { return "\n Can not map available parameters to expected parameters\n\n Mapped parameters:\n ".concat(block(Object.keys(mappedParameters)
3317
+ .map(function (parameterName) { return "- {".concat(parameterName, "}"); })
3318
+ .join('\n')), "\n\n Expected parameters which can not be mapped:\n ").concat(block(Array.from(expectedParameterNames)
3319
+ .map(function (parameterName) { return "- {".concat(parameterName, "}"); })
3320
+ .join('\n')), "\n\n Remaining available parameters:\n ").concat(block(Array.from(availableParametersNames)
3321
+ .map(function (parameterName) { return "- {".concat(parameterName, "}"); })
3322
+ .join('\n')), "\n\n "); }));
3323
+ }
3324
+ var expectedParameterNamesArray = Array.from(expectedParameterNames);
3325
+ var availableParametersNamesArray = Array.from(availableParametersNames);
3326
+ for (var i = 0; i < expectedParameterNames.size; i++) {
3327
+ mappedParameters[expectedParameterNamesArray[i]] = availableParameters[availableParametersNamesArray[i]];
3328
+ }
3329
+ // Note: [👨‍👨‍👧] Now we can freeze `mappedParameters` to prevent @@@
3330
+ Object.freeze(mappedParameters);
3331
+ return mappedParameters;
3268
3332
  }
3333
+
3269
3334
  /**
3270
- * Function checkExpectations will check if the expectations on given value are met
3335
+ * Extracts all code blocks from markdown.
3271
3336
  *
3272
- * Note: There are two simmilar functions:
3273
- * - `checkExpectations` which throws an error if the expectations are not met
3274
- * - `isPassingExpectations` which returns a boolean
3337
+ * Note: There are multiple simmilar function:
3338
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
3339
+ * - `extractJsonBlock` extracts exactly one valid JSON code block
3340
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
3341
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
3275
3342
  *
3276
- * @returns {boolean} True if the expectations are met
3277
- * @public exported from `@promptbook/core`
3343
+ * @param markdown any valid markdown
3344
+ * @returns code blocks with language and content
3345
+ * @throws {ParseError} if block is not closed properly
3346
+ * @public exported from `@promptbook/markdown-utils`
3278
3347
  */
3279
- function isPassingExpectations(expectations, value) {
3348
+ function extractAllBlocksFromMarkdown(markdown) {
3349
+ var e_1, _a;
3350
+ var codeBlocks = [];
3351
+ var lines = markdown.split('\n');
3352
+ // Note: [0] Ensure that the last block notated by gt > will be closed
3353
+ lines.push('');
3354
+ var currentCodeBlock = null;
3280
3355
  try {
3281
- checkExpectations(expectations, value);
3282
- return true;
3356
+ for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
3357
+ var line = lines_1_1.value;
3358
+ if (line.startsWith('> ') || line === '>') {
3359
+ if (currentCodeBlock === null) {
3360
+ currentCodeBlock = { blockNotation: '>', language: null, content: '' };
3361
+ } /* not else */
3362
+ if (currentCodeBlock.blockNotation === '>') {
3363
+ if (currentCodeBlock.content !== '') {
3364
+ currentCodeBlock.content += '\n';
3365
+ }
3366
+ currentCodeBlock.content += line.slice(2);
3367
+ }
3368
+ }
3369
+ else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '>' /* <- Note: [0] */) {
3370
+ codeBlocks.push(currentCodeBlock);
3371
+ currentCodeBlock = null;
3372
+ }
3373
+ /* not else */
3374
+ if (line.startsWith('```')) {
3375
+ var language = line.slice(3).trim() || null;
3376
+ if (currentCodeBlock === null) {
3377
+ currentCodeBlock = { blockNotation: '```', language: language, content: '' };
3378
+ }
3379
+ else {
3380
+ if (language !== null) {
3381
+ throw new ParseError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed and already opening new ").concat(language, " code block"));
3382
+ }
3383
+ codeBlocks.push(currentCodeBlock);
3384
+ currentCodeBlock = null;
3385
+ }
3386
+ }
3387
+ else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '```') {
3388
+ if (currentCodeBlock.content !== '') {
3389
+ currentCodeBlock.content += '\n';
3390
+ }
3391
+ currentCodeBlock.content += line.split('\\`\\`\\`').join('```') /* <- TODO: Maybe make propper unescape */;
3392
+ }
3393
+ }
3283
3394
  }
3284
- catch (error) {
3285
- if (!(error instanceof ExpectError)) {
3286
- throw error;
3395
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3396
+ finally {
3397
+ try {
3398
+ if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
3287
3399
  }
3288
- return false;
3400
+ finally { if (e_1) throw e_1.error; }
3401
+ }
3402
+ if (currentCodeBlock !== null) {
3403
+ throw new ParseError("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed at the end of the markdown"));
3289
3404
  }
3405
+ return codeBlocks;
3290
3406
  }
3291
3407
  /**
3292
- * TODO: [💝] Unite object for expecting amount and format
3408
+ * TODO: Maybe name for `blockNotation` instead of '```' and '>'
3293
3409
  */
3294
3410
 
3295
3411
  /**
3296
- * Creates executor function from pipeline and execution tools.
3412
+ * Extracts extracts exactly one valid JSON code block
3297
3413
  *
3298
- * @returns The executor function
3299
- * @throws {PipelineLogicError} on logical error in the pipeline
3300
- * @public exported from `@promptbook/core`
3414
+ * - When given string is a valid JSON as it is, it just returns it
3415
+ * - When there is no JSON code block the function throws a `ParseError`
3416
+ * - When there are multiple JSON code blocks the function throws a `ParseError`
3417
+ *
3418
+ * Note: It is not important if marked as ```json BUT if it is VALID JSON
3419
+ * Note: There are multiple simmilar function:
3420
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
3421
+ * - `extractJsonBlock` extracts exactly one valid JSON code block
3422
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
3423
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
3424
+ *
3425
+ * @public exported from `@promptbook/markdown-utils`
3426
+ * @throws {ParseError} if there is no valid JSON block in the markdown
3301
3427
  */
3302
- function createPipelineExecutor(options) {
3303
- var _this = this;
3304
- var pipeline = options.pipeline, tools = options.tools, _a = options.settings, settings = _a === void 0 ? {} : _a;
3305
- var _b = settings.maxExecutionAttempts, maxExecutionAttempts = _b === void 0 ? MAX_EXECUTION_ATTEMPTS : _b, _c = settings.maxParallelCount, maxParallelCount = _c === void 0 ? MAX_PARALLEL_COUNT : _c, _d = settings.isVerbose, isVerbose = _d === void 0 ? IS_VERBOSE : _d, _e = settings.isNotPreparedWarningSupressed, isNotPreparedWarningSupressed = _e === void 0 ? false : _e;
3306
- validatePipeline(pipeline);
3307
- var pipelineIdentification = (function () {
3308
- // Note: This is a 😐 implementation of [🚞]
3309
- var _ = [];
3310
- if (pipeline.sourceFile !== undefined) {
3311
- _.push("File: ".concat(pipeline.sourceFile));
3312
- }
3313
- if (pipeline.pipelineUrl !== undefined) {
3314
- _.push("Url: ".concat(pipeline.pipelineUrl));
3315
- }
3316
- return _.join('\n');
3317
- })();
3318
- var llmTools = joinLlmExecutionTools.apply(void 0, __spreadArray([], __read(arrayableToArray(tools.llm)), false));
3319
- var preparedPipeline;
3320
- if (isPipelinePrepared(pipeline)) {
3321
- preparedPipeline = pipeline;
3428
+ function extractJsonBlock(markdown) {
3429
+ if (isValidJsonString(markdown)) {
3430
+ return markdown;
3322
3431
  }
3323
- else if (isNotPreparedWarningSupressed !== true) {
3324
- console.warn(spaceTrim$1(function (block) { return "\n Pipeline is not prepared\n\n ".concat(block(pipelineIdentification), "\n\n It will be prepared ad-hoc before the first execution and **returned as `preparedPipeline` in `PipelineExecutorResult`**\n But it is recommended to prepare the pipeline during collection preparation\n\n @see more at https://ptbk.io/prepare-pipeline\n "); }));
3432
+ var codeBlocks = extractAllBlocksFromMarkdown(markdown);
3433
+ var jsonBlocks = codeBlocks.filter(function (_a) {
3434
+ var content = _a.content;
3435
+ return isValidJsonString(content);
3436
+ });
3437
+ if (jsonBlocks.length === 0) {
3438
+ throw new Error('There is no valid JSON block in the markdown');
3325
3439
  }
3326
- var pipelineExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
3327
- // TODO:[main] !!! Extract to separate functions and files - ALL FUNCTIONS BELOW
3328
- function getContextForTemplate(template) {
3329
- return __awaiter(this, void 0, void 0, function () {
3330
- return __generator(this, function (_a) {
3331
- TODO_USE(template);
3332
- return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [🏍] Implement */];
3333
- });
3334
- });
3440
+ if (jsonBlocks.length > 1) {
3441
+ throw new Error('There are multiple JSON code blocks in the markdown');
3442
+ }
3443
+ return jsonBlocks[0].content;
3444
+ }
3445
+ /**
3446
+ * TODO: Add some auto-healing logic + extract YAML, JSON5, TOML, etc.
3447
+ * TODO: [🏢] Make this logic part of `JsonFormatDefinition` or `isValidJsonString`
3448
+ */
3449
+
3450
+ /**
3451
+ * Just says that the variable is not used but should be kept
3452
+ * No side effects.
3453
+ *
3454
+ * Note: It can be usefull for:
3455
+ *
3456
+ * 1) Suppressing eager optimization of unused imports
3457
+ * 2) Suppressing eslint errors of unused variables in the tests
3458
+ * 3) Keeping the type of the variable for type testing
3459
+ *
3460
+ * @param value any values
3461
+ * @returns void
3462
+ * @private within the repository
3463
+ */
3464
+ function keepUnused() {
3465
+ var valuesToKeep = [];
3466
+ for (var _i = 0; _i < arguments.length; _i++) {
3467
+ valuesToKeep[_i] = arguments[_i];
3468
+ }
3469
+ }
3470
+
3471
+ /**
3472
+ * Replaces parameters in template with values from parameters object
3473
+ *
3474
+ * @param template the template with parameters in {curly} braces
3475
+ * @param parameters the object with parameters
3476
+ * @returns the template with replaced parameters
3477
+ * @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
3478
+ * @public exported from `@promptbook/utils`
3479
+ */
3480
+ function replaceParameters(template, parameters) {
3481
+ var e_1, _a;
3482
+ try {
3483
+ for (var _b = __values(Object.entries(parameters)), _c = _b.next(); !_c.done; _c = _b.next()) {
3484
+ var _d = __read(_c.value, 2), parameterName = _d[0], parameterValue = _d[1];
3485
+ if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
3486
+ throw new UnexpectedError("Parameter {".concat(parameterName, "} has missing value"));
3487
+ }
3488
+ else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
3489
+ // TODO: [🍵]
3490
+ throw new UnexpectedError("Parameter {".concat(parameterName, "} is restricted to use"));
3491
+ }
3335
3492
  }
3336
- function getKnowledgeForTemplate(template) {
3337
- return __awaiter(this, void 0, void 0, function () {
3338
- return __generator(this, function (_a) {
3339
- // TODO: [♨] Implement Better - use real index and keyword search from `template` and {samples}
3340
- TODO_USE(template);
3341
- return [2 /*return*/, preparedPipeline.knowledgePieces.map(function (_a) {
3342
- var content = _a.content;
3343
- return "- ".concat(content);
3344
- }).join('\n')];
3345
- });
3346
- });
3493
+ }
3494
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3495
+ finally {
3496
+ try {
3497
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3347
3498
  }
3348
- function getSamplesForTemplate(template) {
3349
- return __awaiter(this, void 0, void 0, function () {
3350
- return __generator(this, function (_a) {
3351
- // TODO: [♨] Implement Better - use real index and keyword search
3352
- TODO_USE(template);
3353
- return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [♨] Implement */];
3354
- });
3355
- });
3499
+ finally { if (e_1) throw e_1.error; }
3500
+ }
3501
+ var replacedTemplate = template;
3502
+ var match;
3503
+ var loopLimit = LOOP_LIMIT;
3504
+ var _loop_1 = function () {
3505
+ if (loopLimit-- < 0) {
3506
+ throw new LimitReachedError('Loop limit reached during parameters replacement in `replaceParameters`');
3356
3507
  }
3357
- function getReservedParametersForTemplate(template) {
3358
- return __awaiter(this, void 0, void 0, function () {
3359
- var context, knowledge, samples, currentDate, modelName, reservedParameters, _loop_3, RESERVED_PARAMETER_NAMES_1, RESERVED_PARAMETER_NAMES_1_1, parameterName;
3360
- var e_3, _a;
3361
- return __generator(this, function (_b) {
3362
- switch (_b.label) {
3363
- case 0: return [4 /*yield*/, getContextForTemplate(template)];
3364
- case 1:
3365
- context = _b.sent();
3366
- return [4 /*yield*/, getKnowledgeForTemplate(template)];
3367
- case 2:
3368
- knowledge = _b.sent();
3369
- return [4 /*yield*/, getSamplesForTemplate(template)];
3370
- case 3:
3371
- samples = _b.sent();
3372
- currentDate = new Date().toISOString();
3373
- modelName = RESERVED_PARAMETER_MISSING_VALUE;
3374
- reservedParameters = {
3375
- content: RESERVED_PARAMETER_RESTRICTED,
3376
- context: context,
3377
- knowledge: knowledge,
3378
- samples: samples,
3379
- currentDate: currentDate,
3380
- modelName: modelName,
3381
- };
3382
- _loop_3 = function (parameterName) {
3383
- if (reservedParameters[parameterName] === undefined) {
3384
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Reserved parameter {".concat(parameterName, "} is not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3385
- }
3386
- };
3387
- try {
3388
- // Note: Doublecheck that ALL reserved parameters are defined:
3389
- for (RESERVED_PARAMETER_NAMES_1 = __values(RESERVED_PARAMETER_NAMES), RESERVED_PARAMETER_NAMES_1_1 = RESERVED_PARAMETER_NAMES_1.next(); !RESERVED_PARAMETER_NAMES_1_1.done; RESERVED_PARAMETER_NAMES_1_1 = RESERVED_PARAMETER_NAMES_1.next()) {
3390
- parameterName = RESERVED_PARAMETER_NAMES_1_1.value;
3391
- _loop_3(parameterName);
3392
- }
3393
- }
3394
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
3395
- finally {
3396
- try {
3397
- if (RESERVED_PARAMETER_NAMES_1_1 && !RESERVED_PARAMETER_NAMES_1_1.done && (_a = RESERVED_PARAMETER_NAMES_1.return)) _a.call(RESERVED_PARAMETER_NAMES_1);
3398
- }
3399
- finally { if (e_3) throw e_3.error; }
3400
- }
3401
- return [2 /*return*/, reservedParameters];
3402
- }
3403
- });
3404
- });
3508
+ var precol = match.groups.precol;
3509
+ var parameterName = match.groups.parameterName;
3510
+ if (parameterName === '') {
3511
+ return "continue";
3405
3512
  }
3406
- function executeSingleTemplate(currentTemplate) {
3407
- return __awaiter(this, void 0, void 0, function () {
3408
- var name, title, priority, progress_1, usedParameterNames, dependentParameterNames, definedParameters, _a, _b, _c, definedParameterNames, parameters, _loop_4, _d, _e, parameterName, prompt, chatResult, completionResult, embeddingResult, result, resultString, expectError, scriptPipelineExecutionErrors, maxAttempts, jokerParameterNames, preparedContent, _loop_5, attempt, state_2, progress_2;
3409
- var e_4, _f, _g;
3410
- return __generator(this, function (_h) {
3411
- switch (_h.label) {
3412
- case 0:
3413
- name = "pipeline-executor-frame-".concat(currentTemplate.name);
3414
- title = currentTemplate.title;
3415
- priority = preparedPipeline.templates.length - preparedPipeline.templates.indexOf(currentTemplate);
3416
- if (!(onProgress !== undefined) /* <- [3] */) return [3 /*break*/, 2]; /* <- [3] */
3417
- progress_1 = {
3418
- name: name,
3419
- title: title,
3420
- isStarted: false,
3421
- isDone: false,
3422
- templateType: currentTemplate.templateType,
3423
- parameterName: currentTemplate.resultingParameterName,
3424
- parameterValue: null,
3425
- // <- [3]
3426
- };
3427
- if (isReturned) {
3428
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Can not call `onProgress` after pipeline execution is finished \uD83C\uDF4F\n\n ".concat(block(pipelineIdentification), "\n\n ").concat(block(JSON.stringify(progress_1, null, 4)
3429
- .split('\n')
3430
- .map(function (line) { return "> ".concat(line); })
3431
- .join('\n')), "\n "); }));
3432
- }
3433
- return [4 /*yield*/, onProgress(progress_1)];
3434
- case 1:
3435
- _h.sent();
3436
- _h.label = 2;
3437
- case 2:
3438
- usedParameterNames = extractParameterNamesFromTemplate(currentTemplate);
3439
- dependentParameterNames = new Set(currentTemplate.dependentParameterNames);
3440
- if (union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)).size !== 0) {
3441
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Dependent parameters are not consistent with used parameters:\n\n ".concat(block(pipelineIdentification), "\n\n Dependent parameters:\n ").concat(Array.from(dependentParameterNames)
3442
- .map(function (name) { return "{".concat(name, "}"); })
3443
- .join(', '), "\n\n Used parameters:\n ").concat(Array.from(usedParameterNames)
3444
- .map(function (name) { return "{".concat(name, "}"); })
3445
- .join(', '), "\n\n "); }));
3446
- }
3447
- _b = (_a = Object).freeze;
3448
- _c = [{}];
3449
- return [4 /*yield*/, getReservedParametersForTemplate(currentTemplate)];
3450
- case 3:
3451
- definedParameters = _b.apply(_a, [__assign.apply(void 0, [__assign.apply(void 0, _c.concat([(_h.sent())])), parametersToPass])]);
3452
- definedParameterNames = new Set(Object.keys(definedParameters));
3453
- parameters = {};
3454
- _loop_4 = function (parameterName) {
3455
- // Situation: Parameter is defined and used
3456
- if (definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
3457
- parameters[parameterName] = definedParameters[parameterName];
3458
- }
3459
- // Situation: Parameter is defined but NOT used
3460
- else if (definedParameterNames.has(parameterName) && !usedParameterNames.has(parameterName)) ;
3461
- // Situation: Parameter is NOT defined BUT used
3462
- else if (!definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
3463
- // Houston, we have a problem
3464
- // Note: Checking part is also done in `validatePipeline`, but it’s good to doublecheck
3465
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Parameter {".concat(parameterName, "} is NOT defined\n BUT used in template \"").concat(currentTemplate.title || currentTemplate.name, "\"\n\n This should be catched in `validatePipeline`\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3466
- }
3467
- };
3468
- try {
3469
- // Note: [2] Check that all used parameters are defined and removing unused parameters for this template
3470
- for (_d = __values(Array.from(union(definedParameterNames, usedParameterNames, dependentParameterNames))), _e = _d.next(); !_e.done; _e = _d.next()) {
3471
- parameterName = _e.value;
3472
- _loop_4(parameterName);
3473
- }
3474
- }
3475
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
3476
- finally {
3477
- try {
3478
- if (_e && !_e.done && (_f = _d.return)) _f.call(_d);
3479
- }
3480
- finally { if (e_4) throw e_4.error; }
3481
- }
3482
- // Note: Now we can freeze `parameters` because we are sure that all and only used parameters are defined
3483
- Object.freeze(parameters);
3484
- result = null;
3485
- resultString = null;
3486
- expectError = null;
3487
- maxAttempts = currentTemplate.templateType === 'DIALOG_TEMPLATE' ? Infinity : maxExecutionAttempts;
3488
- jokerParameterNames = currentTemplate.jokerParameterNames || [];
3489
- preparedContent = (currentTemplate.preparedContent || '{content}')
3490
- .split('{content}')
3491
- .join(currentTemplate.content);
3492
- _loop_5 = function (attempt) {
3493
- var isJokerAttempt, jokerParameterName, _j, modelRequirements, _k, _l, _m, scriptTools, error_2, e_5_1, _o, _p, functionName, postprocessingError, _q, _r, scriptTools, error_3, e_6_1, e_7_1, error_4;
3494
- var e_5, _s, e_7, _t, e_6, _u;
3495
- return __generator(this, function (_v) {
3496
- switch (_v.label) {
3497
- case 0:
3498
- isJokerAttempt = attempt < 0;
3499
- jokerParameterName = jokerParameterNames[jokerParameterNames.length + attempt];
3500
- if (isJokerAttempt && !jokerParameterName) {
3501
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Joker not found in attempt ".concat(attempt, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
3502
- }
3503
- result = null;
3504
- resultString = null;
3505
- expectError = null;
3506
- if (isJokerAttempt) {
3507
- if (parameters[jokerParameterName] === undefined) {
3508
- throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Joker parameter {".concat(jokerParameterName, "} not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3509
- // <- TODO: This is maybe `PipelineLogicError` which should be detected in `validatePipeline` and here just thrown as `UnexpectedError`
3510
- }
3511
- else {
3512
- resultString = parameters[jokerParameterName];
3513
- }
3514
- }
3515
- _v.label = 1;
3516
- case 1:
3517
- _v.trys.push([1, 44, 45, 46]);
3518
- if (!!isJokerAttempt) return [3 /*break*/, 26];
3519
- _j = currentTemplate.templateType;
3520
- switch (_j) {
3521
- case 'SIMPLE_TEMPLATE': return [3 /*break*/, 2];
3522
- case 'PROMPT_TEMPLATE': return [3 /*break*/, 3];
3523
- case 'SCRIPT_TEMPLATE': return [3 /*break*/, 12];
3524
- case 'DIALOG_TEMPLATE': return [3 /*break*/, 23];
3525
- }
3526
- return [3 /*break*/, 25];
3527
- case 2:
3528
- resultString = replaceParameters(preparedContent, parameters);
3529
- return [3 /*break*/, 26];
3530
- case 3:
3531
- modelRequirements = __assign(__assign({ modelVariant: 'CHAT' }, (pipeline.defaultModelRequirements || {})), (currentTemplate.modelRequirements || {}));
3532
- prompt = {
3533
- title: currentTemplate.title,
3534
- pipelineUrl: "".concat(preparedPipeline.pipelineUrl
3535
- ? preparedPipeline.pipelineUrl
3536
- : 'anonymous' /* <- TODO: [🧠] How to deal with anonymous pipelines, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(currentTemplate.name),
3537
- parameters: parameters,
3538
- content: preparedContent,
3539
- modelRequirements: modelRequirements,
3540
- expectations: __assign(__assign({}, (preparedPipeline.personas.find(function (_a) {
3541
- var name = _a.name;
3542
- return name === currentTemplate.personaName;
3543
- }) || {})), currentTemplate.expectations),
3544
- format: currentTemplate.format,
3545
- postprocessingFunctionNames: currentTemplate.postprocessingFunctionNames,
3546
- }; // <- TODO: Not very good type guard
3547
- _k = modelRequirements.modelVariant;
3548
- switch (_k) {
3549
- case 'CHAT': return [3 /*break*/, 4];
3550
- case 'COMPLETION': return [3 /*break*/, 6];
3551
- case 'EMBEDDING': return [3 /*break*/, 8];
3552
- }
3553
- return [3 /*break*/, 10];
3554
- case 4: return [4 /*yield*/, llmTools.callChatModel($deepFreeze(prompt))];
3555
- case 5:
3556
- chatResult = _v.sent();
3557
- // TODO: [🍬] Destroy chatThread
3558
- result = chatResult;
3559
- resultString = chatResult.content;
3560
- return [3 /*break*/, 11];
3561
- case 6: return [4 /*yield*/, llmTools.callCompletionModel($deepFreeze(prompt))];
3562
- case 7:
3563
- completionResult = _v.sent();
3564
- result = completionResult;
3565
- resultString = completionResult.content;
3566
- return [3 /*break*/, 11];
3567
- case 8: return [4 /*yield*/, llmTools.callEmbeddingModel($deepFreeze(prompt))];
3568
- case 9:
3569
- embeddingResult = _v.sent();
3570
- result = embeddingResult;
3571
- resultString = embeddingResult.content.join(',');
3572
- return [3 /*break*/, 11];
3573
- case 10: throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Unknown model variant \"".concat(currentTemplate.modelRequirements
3574
- .modelVariant, "\"\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3575
- case 11: return [3 /*break*/, 26];
3576
- case 12:
3577
- if (arrayableToArray(tools.script).length === 0) {
3578
- throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n No script execution tools are available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3579
- }
3580
- if (!currentTemplate.contentLanguage) {
3581
- throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Script language is not defined for SCRIPT TEMPLATE \"".concat(currentTemplate.name, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3582
- }
3583
- // TODO: DRY [1]
3584
- scriptPipelineExecutionErrors = [];
3585
- _v.label = 13;
3586
- case 13:
3587
- _v.trys.push([13, 20, 21, 22]);
3588
- _l = (e_5 = void 0, __values(arrayableToArray(tools.script))), _m = _l.next();
3589
- _v.label = 14;
3590
- case 14:
3591
- if (!!_m.done) return [3 /*break*/, 19];
3592
- scriptTools = _m.value;
3593
- _v.label = 15;
3594
- case 15:
3595
- _v.trys.push([15, 17, , 18]);
3596
- return [4 /*yield*/, scriptTools.execute($deepFreeze({
3597
- scriptLanguage: currentTemplate.contentLanguage,
3598
- script: preparedContent,
3599
- parameters: parameters,
3600
- }))];
3601
- case 16:
3602
- resultString = _v.sent();
3603
- return [3 /*break*/, 19];
3604
- case 17:
3605
- error_2 = _v.sent();
3606
- if (!(error_2 instanceof Error)) {
3607
- throw error_2;
3608
- }
3609
- if (error_2 instanceof UnexpectedError) {
3610
- throw error_2;
3611
- }
3612
- scriptPipelineExecutionErrors.push(error_2);
3613
- return [3 /*break*/, 18];
3614
- case 18:
3615
- _m = _l.next();
3616
- return [3 /*break*/, 14];
3617
- case 19: return [3 /*break*/, 22];
3618
- case 20:
3619
- e_5_1 = _v.sent();
3620
- e_5 = { error: e_5_1 };
3621
- return [3 /*break*/, 22];
3622
- case 21:
3623
- try {
3624
- if (_m && !_m.done && (_s = _l.return)) _s.call(_l);
3625
- }
3626
- finally { if (e_5) throw e_5.error; }
3627
- return [7 /*endfinally*/];
3628
- case 22:
3629
- if (resultString !== null) {
3630
- return [3 /*break*/, 26];
3631
- }
3632
- if (scriptPipelineExecutionErrors.length === 1) {
3633
- throw scriptPipelineExecutionErrors[0];
3634
- }
3635
- else {
3636
- throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Script execution failed ".concat(scriptPipelineExecutionErrors.length, " times\n\n ").concat(block(pipelineIdentification), "\n\n ").concat(block(scriptPipelineExecutionErrors
3637
- .map(function (error) { return '- ' + error.message; })
3638
- .join('\n\n')), "\n "); }));
3639
- }
3640
- case 23:
3641
- if (tools.userInterface === undefined) {
3642
- throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n User interface tools are not available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3643
- }
3644
- return [4 /*yield*/, tools.userInterface.promptDialog($deepFreeze({
3645
- promptTitle: currentTemplate.title,
3646
- promptMessage: replaceParameters(currentTemplate.description || '', parameters),
3647
- defaultValue: replaceParameters(preparedContent, parameters),
3648
- // TODO: [🧠] !! Figure out how to define placeholder in .ptbk.md file
3649
- placeholder: undefined,
3650
- priority: priority,
3651
- }))];
3652
- case 24:
3653
- // TODO: [🌹] When making next attempt for `DIALOG TEMPLATE`, preserve the previous user input
3654
- resultString = _v.sent();
3655
- return [3 /*break*/, 26];
3656
- case 25: throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Unknown execution type \"".concat(currentTemplate.templateType, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3657
- case 26:
3658
- if (!(!isJokerAttempt && currentTemplate.postprocessingFunctionNames)) return [3 /*break*/, 43];
3659
- _v.label = 27;
3660
- case 27:
3661
- _v.trys.push([27, 41, 42, 43]);
3662
- _o = (e_7 = void 0, __values(currentTemplate.postprocessingFunctionNames)), _p = _o.next();
3663
- _v.label = 28;
3664
- case 28:
3665
- if (!!_p.done) return [3 /*break*/, 40];
3666
- functionName = _p.value;
3667
- // TODO: DRY [1]
3668
- scriptPipelineExecutionErrors = [];
3669
- postprocessingError = null;
3670
- _v.label = 29;
3671
- case 29:
3672
- _v.trys.push([29, 36, 37, 38]);
3673
- _q = (e_6 = void 0, __values(arrayableToArray(tools.script))), _r = _q.next();
3674
- _v.label = 30;
3675
- case 30:
3676
- if (!!_r.done) return [3 /*break*/, 35];
3677
- scriptTools = _r.value;
3678
- _v.label = 31;
3679
- case 31:
3680
- _v.trys.push([31, 33, , 34]);
3681
- return [4 /*yield*/, scriptTools.execute({
3682
- scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
3683
- script: "".concat(functionName, "(resultString)"),
3684
- parameters: {
3685
- resultString: resultString || '',
3686
- // Note: No ...parametersForTemplate, because working with result only
3687
- },
3688
- })];
3689
- case 32:
3690
- resultString = _v.sent();
3691
- postprocessingError = null;
3692
- return [3 /*break*/, 35];
3693
- case 33:
3694
- error_3 = _v.sent();
3695
- if (!(error_3 instanceof Error)) {
3696
- throw error_3;
3697
- }
3698
- if (error_3 instanceof UnexpectedError) {
3699
- throw error_3;
3700
- }
3701
- postprocessingError = error_3;
3702
- scriptPipelineExecutionErrors.push(error_3);
3703
- return [3 /*break*/, 34];
3704
- case 34:
3705
- _r = _q.next();
3706
- return [3 /*break*/, 30];
3707
- case 35: return [3 /*break*/, 38];
3708
- case 36:
3709
- e_6_1 = _v.sent();
3710
- e_6 = { error: e_6_1 };
3711
- return [3 /*break*/, 38];
3712
- case 37:
3713
- try {
3714
- if (_r && !_r.done && (_u = _q.return)) _u.call(_q);
3715
- }
3716
- finally { if (e_6) throw e_6.error; }
3717
- return [7 /*endfinally*/];
3718
- case 38:
3719
- if (postprocessingError) {
3720
- throw postprocessingError;
3721
- }
3722
- _v.label = 39;
3723
- case 39:
3724
- _p = _o.next();
3725
- return [3 /*break*/, 28];
3726
- case 40: return [3 /*break*/, 43];
3727
- case 41:
3728
- e_7_1 = _v.sent();
3729
- e_7 = { error: e_7_1 };
3730
- return [3 /*break*/, 43];
3731
- case 42:
3732
- try {
3733
- if (_p && !_p.done && (_t = _o.return)) _t.call(_o);
3734
- }
3735
- finally { if (e_7) throw e_7.error; }
3736
- return [7 /*endfinally*/];
3737
- case 43:
3738
- // TODO: [💝] Unite object for expecting amount and format
3739
- if (currentTemplate.format) {
3740
- if (currentTemplate.format === 'JSON') {
3741
- if (!isValidJsonString(resultString || '')) {
3742
- // TODO: [🏢] Do more universally via `FormatDefinition`
3743
- try {
3744
- resultString = extractJsonBlock(resultString || '');
3745
- }
3746
- catch (error) {
3747
- keepUnused(error);
3748
- throw new ExpectError(spaceTrim$1(function (block) { return "\n Expected valid JSON string\n\n ".concat(block(
3749
- /*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ ''), "\n "); }));
3750
- }
3751
- }
3513
+ if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
3514
+ throw new PipelineExecutionError('Parameter is already opened or not closed');
3515
+ }
3516
+ if (parameters[parameterName] === undefined) {
3517
+ throw new PipelineExecutionError("Parameter {".concat(parameterName, "} is not defined"));
3518
+ }
3519
+ var parameterValue = parameters[parameterName];
3520
+ if (parameterValue === undefined) {
3521
+ throw new PipelineExecutionError("Parameter {".concat(parameterName, "} is not defined"));
3522
+ }
3523
+ parameterValue = parameterValue.toString();
3524
+ if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
3525
+ parameterValue = parameterValue
3526
+ .split('\n')
3527
+ .map(function (line, index) { return (index === 0 ? line : "".concat(precol).concat(line)); })
3528
+ .join('\n');
3529
+ }
3530
+ replacedTemplate =
3531
+ replacedTemplate.substring(0, match.index + precol.length) +
3532
+ parameterValue +
3533
+ replacedTemplate.substring(match.index + precol.length + parameterName.length + 2);
3534
+ };
3535
+ while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
3536
+ .exec(replacedTemplate))) {
3537
+ _loop_1();
3538
+ }
3539
+ // [💫] Check if there are parameters that are not closed properly
3540
+ if (/{\w+$/.test(replacedTemplate)) {
3541
+ throw new PipelineExecutionError('Parameter is not closed');
3542
+ }
3543
+ // [💫] Check if there are parameters that are not opened properly
3544
+ if (/^\w+}/.test(replacedTemplate)) {
3545
+ throw new PipelineExecutionError('Parameter is not opened');
3546
+ }
3547
+ return replacedTemplate;
3548
+ }
3549
+
3550
+ /**
3551
+ * Counts number of characters in the text
3552
+ *
3553
+ * @public exported from `@promptbook/utils`
3554
+ */
3555
+ function countCharacters(text) {
3556
+ // Remove null characters
3557
+ text = text.replace(/\0/g, '');
3558
+ // Replace emojis (and also ZWJ sequence) with hyphens
3559
+ text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
3560
+ text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
3561
+ text = text.replace(/\p{Extended_Pictographic}(\u{200D}\p{Extended_Pictographic})*/gu, '-');
3562
+ return text.length;
3563
+ }
3564
+
3565
+ /**
3566
+ * Counts number of lines in the text
3567
+ *
3568
+ * @public exported from `@promptbook/utils`
3569
+ */
3570
+ function countLines(text) {
3571
+ if (text === '') {
3572
+ return 0;
3573
+ }
3574
+ return text.split('\n').length;
3575
+ }
3576
+
3577
+ /**
3578
+ * Counts number of pages in the text
3579
+ *
3580
+ * @public exported from `@promptbook/utils`
3581
+ */
3582
+ function countPages(text) {
3583
+ var sentencesPerPage = 5; // Assuming each page has 5 sentences
3584
+ var sentences = text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
3585
+ var pageCount = Math.ceil(sentences.length / sentencesPerPage);
3586
+ return pageCount;
3587
+ }
3588
+
3589
+ /**
3590
+ * Counts number of paragraphs in the text
3591
+ *
3592
+ * @public exported from `@promptbook/utils`
3593
+ */
3594
+ function countParagraphs(text) {
3595
+ return text.split(/\n\s*\n/).filter(function (paragraph) { return paragraph.trim() !== ''; }).length;
3596
+ }
3597
+
3598
+ /**
3599
+ * Split text into sentences
3600
+ *
3601
+ * @public exported from `@promptbook/utils`
3602
+ */
3603
+ function splitIntoSentences(text) {
3604
+ return text.split(/[.!?]+/).filter(function (sentence) { return sentence.trim() !== ''; });
3605
+ }
3606
+ /**
3607
+ * Counts number of sentences in the text
3608
+ *
3609
+ * @public exported from `@promptbook/utils`
3610
+ */
3611
+ function countSentences(text) {
3612
+ return splitIntoSentences(text).length;
3613
+ }
3614
+
3615
+ /**
3616
+ * Counts number of words in the text
3617
+ *
3618
+ * @public exported from `@promptbook/utils`
3619
+ */
3620
+ function countWords(text) {
3621
+ text = text.replace(/[\p{Extended_Pictographic}]/gu, 'a');
3622
+ text = removeDiacritics(text);
3623
+ return text.split(/[^a-zа-я0-9]+/i).filter(function (word) { return word.length > 0; }).length;
3624
+ }
3625
+
3626
+ /**
3627
+ * Index of all counter functions
3628
+ *
3629
+ * @public exported from `@promptbook/utils`
3630
+ */
3631
+ var CountUtils = {
3632
+ CHARACTERS: countCharacters,
3633
+ WORDS: countWords,
3634
+ SENTENCES: countSentences,
3635
+ PARAGRAPHS: countParagraphs,
3636
+ LINES: countLines,
3637
+ PAGES: countPages,
3638
+ };
3639
+ /**
3640
+ * TODO: [🧠][🤠] This should be probbably as part of `TextFormatDefinition`
3641
+ */
3642
+
3643
+ /**
3644
+ * Function checkExpectations will check if the expectations on given value are met
3645
+ *
3646
+ * Note: There are two simmilar functions:
3647
+ * - `checkExpectations` which throws an error if the expectations are not met
3648
+ * - `isPassingExpectations` which returns a boolean
3649
+ *
3650
+ * @throws {ExpectError} if the expectations are not met
3651
+ * @returns {void} Nothing
3652
+ * @private internal function of `createPipelineExecutor`
3653
+ */
3654
+ function checkExpectations(expectations, value) {
3655
+ var e_1, _a;
3656
+ try {
3657
+ for (var _b = __values(Object.entries(expectations)), _c = _b.next(); !_c.done; _c = _b.next()) {
3658
+ var _d = __read(_c.value, 2), unit = _d[0], _e = _d[1], max = _e.max, min = _e.min;
3659
+ var amount = CountUtils[unit.toUpperCase()](value);
3660
+ if (min && amount < min) {
3661
+ throw new ExpectError("Expected at least ".concat(min, " ").concat(unit, " but got ").concat(amount));
3662
+ } /* not else */
3663
+ if (max && amount > max) {
3664
+ throw new ExpectError("Expected at most ".concat(max, " ").concat(unit, " but got ").concat(amount));
3665
+ }
3666
+ }
3667
+ }
3668
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3669
+ finally {
3670
+ try {
3671
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3672
+ }
3673
+ finally { if (e_1) throw e_1.error; }
3674
+ }
3675
+ }
3676
+ /**
3677
+ * Function checkExpectations will check if the expectations on given value are met
3678
+ *
3679
+ * Note: There are two simmilar functions:
3680
+ * - `checkExpectations` which throws an error if the expectations are not met
3681
+ * - `isPassingExpectations` which returns a boolean
3682
+ *
3683
+ * @returns {boolean} True if the expectations are met
3684
+ * @public exported from `@promptbook/core`
3685
+ */
3686
+ function isPassingExpectations(expectations, value) {
3687
+ try {
3688
+ checkExpectations(expectations, value);
3689
+ return true;
3690
+ }
3691
+ catch (error) {
3692
+ if (!(error instanceof ExpectError)) {
3693
+ throw error;
3694
+ }
3695
+ return false;
3696
+ }
3697
+ }
3698
+ /**
3699
+ * TODO: [💝] Unite object for expecting amount and format
3700
+ * TODO: [🧠][🤠] This should be part of `TextFormatDefinition`
3701
+ * Note: [💝] and [🤠] are interconnected together
3702
+ */
3703
+
3704
+ /**
3705
+ * @@@
3706
+ *
3707
+ * @private internal utility of `createPipelineExecutor`
3708
+ */
3709
+ function executeAttempts(options) {
3710
+ return __awaiter(this, void 0, void 0, function () {
3711
+ var jokerParameterNames, priority, maxAttempts, preparedContent, parameters, template, preparedPipeline, tools, llmTools, settings, $executionReport, pipelineIdentification, maxExecutionAttempts, $ongoingTemplateResult, _loop_1, attempt, state_1;
3712
+ return __generator(this, function (_a) {
3713
+ switch (_a.label) {
3714
+ case 0:
3715
+ 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;
3716
+ maxExecutionAttempts = settings.maxExecutionAttempts;
3717
+ $ongoingTemplateResult = {
3718
+ $result: null,
3719
+ $resultString: null,
3720
+ $expectError: null,
3721
+ $scriptPipelineExecutionErrors: [],
3722
+ };
3723
+ _loop_1 = function (attempt) {
3724
+ 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;
3725
+ var e_1, _q, e_3, _r, e_2, _s;
3726
+ return __generator(this, function (_t) {
3727
+ switch (_t.label) {
3728
+ case 0:
3729
+ isJokerAttempt = attempt < 0;
3730
+ jokerParameterName = jokerParameterNames[jokerParameterNames.length + attempt];
3731
+ // TODO: [🧠][🍭] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
3732
+ if (isJokerAttempt && !jokerParameterName) {
3733
+ throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Joker not found in attempt ".concat(attempt, "\n\n ").concat(block(pipelineIdentification), "\n "); }));
3734
+ }
3735
+ $ongoingTemplateResult.$result = null;
3736
+ $ongoingTemplateResult.$resultString = null;
3737
+ $ongoingTemplateResult.$expectError = null;
3738
+ if (isJokerAttempt) {
3739
+ if (parameters[jokerParameterName] === undefined) {
3740
+ throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Joker parameter {".concat(jokerParameterName, "} not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
3741
+ // <- TODO: This is maybe `PipelineLogicError` which should be detected in `validatePipeline` and here just thrown as `UnexpectedError`
3742
+ }
3743
+ else {
3744
+ $ongoingTemplateResult.$resultString = parameters[jokerParameterName];
3745
+ }
3746
+ }
3747
+ _t.label = 1;
3748
+ case 1:
3749
+ _t.trys.push([1, 43, 44, 45]);
3750
+ if (!!isJokerAttempt) return [3 /*break*/, 25];
3751
+ _b = template.templateType;
3752
+ switch (_b) {
3753
+ case 'SIMPLE_TEMPLATE': return [3 /*break*/, 2];
3754
+ case 'PROMPT_TEMPLATE': return [3 /*break*/, 3];
3755
+ case 'SCRIPT_TEMPLATE': return [3 /*break*/, 11];
3756
+ case 'DIALOG_TEMPLATE': return [3 /*break*/, 22];
3757
+ }
3758
+ return [3 /*break*/, 24];
3759
+ case 2:
3760
+ $ongoingTemplateResult.$resultString = replaceParameters(preparedContent, parameters);
3761
+ return [3 /*break*/, 25];
3762
+ case 3:
3763
+ modelRequirements = __assign(__assign({ modelVariant: 'CHAT' }, (preparedPipeline.defaultModelRequirements || {})), (template.modelRequirements || {}));
3764
+ $ongoingTemplateResult.$prompt = {
3765
+ title: template.title,
3766
+ pipelineUrl: "".concat(preparedPipeline.pipelineUrl
3767
+ ? preparedPipeline.pipelineUrl
3768
+ : 'anonymous' /* <- TODO: [🧠] How to deal with anonymous pipelines, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(template.name),
3769
+ parameters: parameters,
3770
+ content: preparedContent,
3771
+ modelRequirements: modelRequirements,
3772
+ expectations: __assign(__assign({}, (preparedPipeline.personas.find(function (_a) {
3773
+ var name = _a.name;
3774
+ return name === template.personaName;
3775
+ }) ||
3776
+ {})), template.expectations),
3777
+ format: template.format,
3778
+ postprocessingFunctionNames: template.postprocessingFunctionNames,
3779
+ }; // <- TODO: Not very good type guard
3780
+ _c = modelRequirements.modelVariant;
3781
+ switch (_c) {
3782
+ case 'CHAT': return [3 /*break*/, 4];
3783
+ case 'COMPLETION': return [3 /*break*/, 6];
3784
+ case 'EMBEDDING': return [3 /*break*/, 8];
3785
+ }
3786
+ return [3 /*break*/, 9];
3787
+ case 4:
3788
+ _d = $ongoingTemplateResult;
3789
+ return [4 /*yield*/, llmTools.callChatModel($deepFreeze($ongoingTemplateResult.$prompt))];
3790
+ case 5:
3791
+ _d.$chatResult = _t.sent();
3792
+ // TODO: [🍬] Destroy chatThread
3793
+ $ongoingTemplateResult.$result = $ongoingTemplateResult.$chatResult;
3794
+ $ongoingTemplateResult.$resultString = $ongoingTemplateResult.$chatResult.content;
3795
+ return [3 /*break*/, 10];
3796
+ case 6:
3797
+ _e = $ongoingTemplateResult;
3798
+ return [4 /*yield*/, llmTools.callCompletionModel($deepFreeze($ongoingTemplateResult.$prompt))];
3799
+ case 7:
3800
+ _e.$completionResult = _t.sent();
3801
+ $ongoingTemplateResult.$result = $ongoingTemplateResult.$completionResult;
3802
+ $ongoingTemplateResult.$resultString =
3803
+ $ongoingTemplateResult.$completionResult.content;
3804
+ return [3 /*break*/, 10];
3805
+ case 8: throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Embedding model can not be used in pipeline\n\n This should be catched during parsing\n\n ".concat(block(pipelineIdentification), "\n\n "); }));
3806
+ case 9: throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Unknown model variant \"".concat(template.modelRequirements.modelVariant, "\"\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
3807
+ case 10: return [3 /*break*/, 25];
3808
+ case 11:
3809
+ if (arrayableToArray(tools.script).length === 0) {
3810
+ throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n No script execution tools are available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3811
+ }
3812
+ if (!template.contentLanguage) {
3813
+ throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Script language is not defined for SCRIPT TEMPLATE \"".concat(template.name, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3814
+ }
3815
+ _t.label = 12;
3816
+ case 12:
3817
+ _t.trys.push([12, 19, 20, 21]);
3818
+ _f = (e_1 = void 0, __values(arrayableToArray(tools.script))), _g = _f.next();
3819
+ _t.label = 13;
3820
+ case 13:
3821
+ if (!!_g.done) return [3 /*break*/, 18];
3822
+ scriptTools = _g.value;
3823
+ _t.label = 14;
3824
+ case 14:
3825
+ _t.trys.push([14, 16, , 17]);
3826
+ _h = $ongoingTemplateResult;
3827
+ return [4 /*yield*/, scriptTools.execute($deepFreeze({
3828
+ scriptLanguage: template.contentLanguage,
3829
+ script: preparedContent,
3830
+ parameters: parameters,
3831
+ }))];
3832
+ case 15:
3833
+ _h.$resultString = _t.sent();
3834
+ return [3 /*break*/, 18];
3835
+ case 16:
3836
+ error_1 = _t.sent();
3837
+ if (!(error_1 instanceof Error)) {
3838
+ throw error_1;
3839
+ }
3840
+ if (error_1 instanceof UnexpectedError) {
3841
+ throw error_1;
3842
+ }
3843
+ $ongoingTemplateResult.$scriptPipelineExecutionErrors.push(error_1);
3844
+ return [3 /*break*/, 17];
3845
+ case 17:
3846
+ _g = _f.next();
3847
+ return [3 /*break*/, 13];
3848
+ case 18: return [3 /*break*/, 21];
3849
+ case 19:
3850
+ e_1_1 = _t.sent();
3851
+ e_1 = { error: e_1_1 };
3852
+ return [3 /*break*/, 21];
3853
+ case 20:
3854
+ try {
3855
+ if (_g && !_g.done && (_q = _f.return)) _q.call(_f);
3856
+ }
3857
+ finally { if (e_1) throw e_1.error; }
3858
+ return [7 /*endfinally*/];
3859
+ case 21:
3860
+ if ($ongoingTemplateResult.$resultString !== null) {
3861
+ return [3 /*break*/, 25];
3862
+ }
3863
+ if ($ongoingTemplateResult.$scriptPipelineExecutionErrors.length === 1) {
3864
+ throw $ongoingTemplateResult.$scriptPipelineExecutionErrors[0];
3865
+ }
3866
+ else {
3867
+ throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Script execution failed ".concat($ongoingTemplateResult.$scriptPipelineExecutionErrors.length, "x\n\n ").concat(block(pipelineIdentification), "\n\n ").concat(block($ongoingTemplateResult.$scriptPipelineExecutionErrors
3868
+ .map(function (error) { return '- ' + error.message; })
3869
+ .join('\n\n')), "\n "); }));
3870
+ }
3871
+ case 22:
3872
+ if (tools.userInterface === undefined) {
3873
+ throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n User interface tools are not available\n\n ".concat(block(pipelineIdentification), "\n "); }));
3874
+ }
3875
+ // TODO: [🌹] When making next attempt for `DIALOG TEMPLATE`, preserve the previous user input
3876
+ _j = $ongoingTemplateResult;
3877
+ return [4 /*yield*/, tools.userInterface.promptDialog($deepFreeze({
3878
+ promptTitle: template.title,
3879
+ promptMessage: replaceParameters(template.description || '', parameters),
3880
+ defaultValue: replaceParameters(preparedContent, parameters),
3881
+ // TODO: [🧠] !! Figure out how to define placeholder in .ptbk.md file
3882
+ placeholder: undefined,
3883
+ priority: priority,
3884
+ }))];
3885
+ case 23:
3886
+ // TODO: [🌹] When making next attempt for `DIALOG TEMPLATE`, preserve the previous user input
3887
+ _j.$resultString = _t.sent();
3888
+ return [3 /*break*/, 25];
3889
+ case 24: throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Unknown execution type \"".concat(template.templateType, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3890
+ case 25:
3891
+ if (!(!isJokerAttempt && template.postprocessingFunctionNames)) return [3 /*break*/, 42];
3892
+ _t.label = 26;
3893
+ case 26:
3894
+ _t.trys.push([26, 40, 41, 42]);
3895
+ _k = (e_3 = void 0, __values(template.postprocessingFunctionNames)), _l = _k.next();
3896
+ _t.label = 27;
3897
+ case 27:
3898
+ if (!!_l.done) return [3 /*break*/, 39];
3899
+ functionName = _l.value;
3900
+ postprocessingError = null;
3901
+ _t.label = 28;
3902
+ case 28:
3903
+ _t.trys.push([28, 35, 36, 37]);
3904
+ _m = (e_2 = void 0, __values(arrayableToArray(tools.script))), _o = _m.next();
3905
+ _t.label = 29;
3906
+ case 29:
3907
+ if (!!_o.done) return [3 /*break*/, 34];
3908
+ scriptTools = _o.value;
3909
+ _t.label = 30;
3910
+ case 30:
3911
+ _t.trys.push([30, 32, , 33]);
3912
+ _p = $ongoingTemplateResult;
3913
+ return [4 /*yield*/, scriptTools.execute({
3914
+ scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
3915
+ script: "".concat(functionName, "(resultString)"),
3916
+ parameters: {
3917
+ resultString: $ongoingTemplateResult.$resultString || '',
3918
+ // Note: No ...parametersForTemplate, because working with result only
3919
+ },
3920
+ })];
3921
+ case 31:
3922
+ _p.$resultString = _t.sent();
3923
+ postprocessingError = null;
3924
+ return [3 /*break*/, 34];
3925
+ case 32:
3926
+ error_2 = _t.sent();
3927
+ if (!(error_2 instanceof Error)) {
3928
+ throw error_2;
3929
+ }
3930
+ if (error_2 instanceof UnexpectedError) {
3931
+ throw error_2;
3932
+ }
3933
+ postprocessingError = error_2;
3934
+ $ongoingTemplateResult.$scriptPipelineExecutionErrors.push(error_2);
3935
+ return [3 /*break*/, 33];
3936
+ case 33:
3937
+ _o = _m.next();
3938
+ return [3 /*break*/, 29];
3939
+ case 34: return [3 /*break*/, 37];
3940
+ case 35:
3941
+ e_2_1 = _t.sent();
3942
+ e_2 = { error: e_2_1 };
3943
+ return [3 /*break*/, 37];
3944
+ case 36:
3945
+ try {
3946
+ if (_o && !_o.done && (_s = _m.return)) _s.call(_m);
3947
+ }
3948
+ finally { if (e_2) throw e_2.error; }
3949
+ return [7 /*endfinally*/];
3950
+ case 37:
3951
+ if (postprocessingError) {
3952
+ throw postprocessingError;
3953
+ }
3954
+ _t.label = 38;
3955
+ case 38:
3956
+ _l = _k.next();
3957
+ return [3 /*break*/, 27];
3958
+ case 39: return [3 /*break*/, 42];
3959
+ case 40:
3960
+ e_3_1 = _t.sent();
3961
+ e_3 = { error: e_3_1 };
3962
+ return [3 /*break*/, 42];
3963
+ case 41:
3964
+ try {
3965
+ if (_l && !_l.done && (_r = _k.return)) _r.call(_k);
3966
+ }
3967
+ finally { if (e_3) throw e_3.error; }
3968
+ return [7 /*endfinally*/];
3969
+ case 42:
3970
+ // TODO: [💝] Unite object for expecting amount and format
3971
+ if (template.format) {
3972
+ if (template.format === 'JSON') {
3973
+ if (!isValidJsonString($ongoingTemplateResult.$resultString || '')) {
3974
+ // TODO: [🏢] Do more universally via `FormatDefinition`
3975
+ try {
3976
+ $ongoingTemplateResult.$resultString = extractJsonBlock($ongoingTemplateResult.$resultString || '');
3752
3977
  }
3753
- else {
3754
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Unknown format \"".concat(currentTemplate.format, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3978
+ catch (error) {
3979
+ keepUnused(error);
3980
+ throw new ExpectError(spaceTrim$1(function (block) { return "\n Expected valid JSON string\n\n ".concat(block(
3981
+ /*<- Note: No need for `pipelineIdentification`, it will be catched and added later */ ''), "\n "); }));
3755
3982
  }
3756
3983
  }
3757
- // TODO: [💝] Unite object for expecting amount and format
3758
- if (currentTemplate.expectations) {
3759
- checkExpectations(currentTemplate.expectations, resultString || '');
3760
- }
3761
- return [2 /*return*/, "break-attempts"];
3762
- case 44:
3763
- error_4 = _v.sent();
3764
- if (!(error_4 instanceof ExpectError)) {
3765
- throw error_4;
3766
- }
3767
- expectError = error_4;
3768
- return [3 /*break*/, 46];
3769
- case 45:
3770
- if (!isJokerAttempt &&
3771
- currentTemplate.templateType === 'PROMPT_TEMPLATE' &&
3772
- prompt
3773
- // <- Note: [2] When some expected parameter is not defined, error will occur in replaceParameters
3774
- // In that case we don’t want to make a report about it because it’s not a llm execution error
3775
- ) {
3776
- // TODO: [🧠] Maybe put other templateTypes into report
3777
- executionReport.promptExecutions.push({
3778
- prompt: __assign({}, prompt),
3779
- result: result || undefined,
3780
- error: expectError === null ? undefined : serializeError(expectError),
3781
- });
3782
- }
3783
- return [7 /*endfinally*/];
3784
- case 46:
3785
- if (expectError !== null && attempt === maxAttempts - 1) {
3786
- throw new PipelineExecutionError(spaceTrim$1(function (block) { return "\n LLM execution failed ".concat(maxExecutionAttempts, "x\n\n ").concat(block(pipelineIdentification), "\n\n ---\n The Prompt:\n ").concat(block(prompt.content
3787
- .split('\n')
3788
- .map(function (line) { return "> ".concat(line); })
3789
- .join('\n')), "\n\n Last error ").concat((expectError === null || expectError === void 0 ? void 0 : expectError.name) || '', ":\n ").concat(block(((expectError === null || expectError === void 0 ? void 0 : expectError.message) || '')
3984
+ }
3985
+ else {
3986
+ throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Unknown format \"".concat(template.format, "\"\n\n ").concat(block(pipelineIdentification), "\n "); }));
3987
+ }
3988
+ }
3989
+ // TODO: [💝] Unite object for expecting amount and format
3990
+ if (template.expectations) {
3991
+ checkExpectations(template.expectations, $ongoingTemplateResult.$resultString || '');
3992
+ }
3993
+ return [2 /*return*/, "break-attempts"];
3994
+ case 43:
3995
+ error_3 = _t.sent();
3996
+ if (!(error_3 instanceof ExpectError)) {
3997
+ throw error_3;
3998
+ }
3999
+ $ongoingTemplateResult.$expectError = error_3;
4000
+ return [3 /*break*/, 45];
4001
+ case 44:
4002
+ if (!isJokerAttempt &&
4003
+ template.templateType === 'PROMPT_TEMPLATE' &&
4004
+ $ongoingTemplateResult.$prompt
4005
+ // <- Note: [2] When some expected parameter is not defined, error will occur in replaceParameters
4006
+ // In that case we don’t want to make a report about it because it’s not a llm execution error
4007
+ ) {
4008
+ // TODO: [🧠] Maybe put other templateTypes into report
4009
+ $executionReport.promptExecutions.push({
4010
+ prompt: __assign({}, $ongoingTemplateResult.$prompt),
4011
+ result: $ongoingTemplateResult.$result || undefined,
4012
+ error: $ongoingTemplateResult.$expectError === null
4013
+ ? undefined
4014
+ : serializeError($ongoingTemplateResult.$expectError),
4015
+ });
4016
+ }
4017
+ return [7 /*endfinally*/];
4018
+ case 45:
4019
+ if ($ongoingTemplateResult.$expectError !== null && attempt === maxAttempts - 1) {
4020
+ throw new PipelineExecutionError(spaceTrim$1(function (block) {
4021
+ var _a, _b, _c;
4022
+ return "\n LLM execution failed ".concat(maxExecutionAttempts, "x\n\n ").concat(block(pipelineIdentification), "\n\n ---\n The Prompt:\n ").concat(block((((_a = $ongoingTemplateResult.$prompt) === null || _a === void 0 ? void 0 : _a.content) || '')
4023
+ .split('\n')
4024
+ .map(function (line) { return "> ".concat(line); })
4025
+ .join('\n')), "\n\n Last error ").concat(((_b = $ongoingTemplateResult.$expectError) === null || _b === void 0 ? void 0 : _b.name) || '', ":\n ").concat(block((((_c = $ongoingTemplateResult.$expectError) === null || _c === void 0 ? void 0 : _c.message) || '')
4026
+ .split('\n')
4027
+ .map(function (line) { return "> ".concat(line); })
4028
+ .join('\n')), "\n\n Last result:\n ").concat(block($ongoingTemplateResult.$resultString === null
4029
+ ? 'null'
4030
+ : $ongoingTemplateResult.$resultString
3790
4031
  .split('\n')
3791
4032
  .map(function (line) { return "> ".concat(line); })
3792
- .join('\n')), "\n\n Last result:\n ").concat(block(resultString === null
3793
- ? 'null'
3794
- : resultString
3795
- .split('\n')
3796
- .map(function (line) { return "> ".concat(line); })
3797
- .join('\n')), "\n ---\n "); }));
3798
- }
3799
- return [2 /*return*/];
4033
+ .join('\n')), "\n ---\n ");
4034
+ }));
3800
4035
  }
3801
- });
3802
- };
3803
- attempt = -jokerParameterNames.length;
3804
- _h.label = 4;
3805
- case 4:
3806
- if (!(attempt < maxAttempts)) return [3 /*break*/, 7];
3807
- return [5 /*yield**/, _loop_5(attempt)];
3808
- case 5:
3809
- state_2 = _h.sent();
3810
- switch (state_2) {
3811
- case "break-attempts": return [3 /*break*/, 7];
3812
- }
3813
- _h.label = 6;
3814
- case 6:
3815
- attempt++;
3816
- return [3 /*break*/, 4];
3817
- case 7:
3818
- if (resultString === null) {
3819
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Something went wrong and prompt result is null\n\n ".concat(block(pipelineIdentification), "\n "); }));
4036
+ return [2 /*return*/];
3820
4037
  }
3821
- if (!(onProgress !== undefined) /* <- [3] */) return [3 /*break*/, 9]; /* <- [3] */
3822
- progress_2 = {
3823
- name: name,
3824
- title: title,
3825
- isStarted: true,
3826
- isDone: true,
3827
- templateType: currentTemplate.templateType,
3828
- parameterName: currentTemplate.resultingParameterName,
3829
- parameterValue: resultString,
3830
- // <- [3]
3831
- };
3832
- if (isReturned) {
3833
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Can not call `onProgress` after pipeline execution is finished \uD83C\uDF4E\n\n ".concat(block(pipelineIdentification), "\n\n ").concat(block(JSON.stringify(progress_2, null, 4)
3834
- .split('\n')
3835
- .map(function (line) { return "> ".concat(line); })
3836
- .join('\n')), "\n\n "); }));
3837
- }
3838
- return [4 /*yield*/, onProgress(progress_2)];
3839
- case 8:
3840
- _h.sent();
3841
- _h.label = 9;
3842
- case 9:
3843
- parametersToPass = Object.freeze(__assign(__assign({}, parametersToPass), (_g = {}, _g[currentTemplate.resultingParameterName] = resultString /* <- Note: Not need to detect parameter collision here because pipeline checks logic consistency during construction */, _g)));
3844
- return [2 /*return*/];
4038
+ });
4039
+ };
4040
+ attempt = -jokerParameterNames.length;
4041
+ _a.label = 1;
4042
+ case 1:
4043
+ if (!(attempt < maxAttempts)) return [3 /*break*/, 4];
4044
+ return [5 /*yield**/, _loop_1(attempt)];
4045
+ case 2:
4046
+ state_1 = _a.sent();
4047
+ switch (state_1) {
4048
+ case "break-attempts": return [3 /*break*/, 4];
3845
4049
  }
3846
- });
3847
- });
3848
- }
3849
- function filterJustOutputParameters() {
3850
- var e_8, _a;
3851
- var outputParameters = {};
3852
- var _loop_6 = function (parameter) {
3853
- if (parametersToPass[parameter.name] === undefined) {
3854
- // [4]
3855
- warnings.push(new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Parameter {".concat(parameter.name, "} should be an output parameter, but it was not generated during pipeline execution\n\n ").concat(block(pipelineIdentification), "\n "); })));
3856
- return "continue";
3857
- }
3858
- outputParameters[parameter.name] = parametersToPass[parameter.name] || '';
3859
- };
3860
- try {
3861
- // Note: Filter ONLY output parameters
3862
- for (var _b = __values(preparedPipeline.parameters.filter(function (_a) {
3863
- var isOutput = _a.isOutput;
3864
- return isOutput;
3865
- })), _c = _b.next(); !_c.done; _c = _b.next()) {
3866
- var parameter = _c.value;
3867
- _loop_6(parameter);
3868
- }
4050
+ _a.label = 3;
4051
+ case 3:
4052
+ attempt++;
4053
+ return [3 /*break*/, 1];
4054
+ case 4:
4055
+ if ($ongoingTemplateResult.$resultString === null) {
4056
+ throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Something went wrong and prompt result is null\n\n ".concat(block(pipelineIdentification), "\n "); }));
4057
+ }
4058
+ return [2 /*return*/, $ongoingTemplateResult.$resultString];
3869
4059
  }
3870
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
3871
- finally {
3872
- try {
3873
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3874
- }
3875
- finally { if (e_8) throw e_8.error; }
4060
+ });
4061
+ });
4062
+ }
4063
+ /**
4064
+ * TODO: Break into smaller functions
4065
+ */
4066
+
4067
+ /**
4068
+ * @@@
4069
+ *
4070
+ * @private internal utility of `createPipelineExecutor`
4071
+ */
4072
+ function executeFormatCells(options) {
4073
+ return __awaiter(this, void 0, void 0, function () {
4074
+ var template, jokerParameterNames, parameters, priority, pipelineIdentification, settings, parameterValue, formatDefinition, subvalueDefinition, formatSettings, resultString;
4075
+ var _this = this;
4076
+ return __generator(this, function (_a) {
4077
+ switch (_a.label) {
4078
+ case 0:
4079
+ template = options.template, jokerParameterNames = options.jokerParameterNames, parameters = options.parameters, priority = options.priority, pipelineIdentification = options.pipelineIdentification, settings = options.settings;
4080
+ if (template.foreach === undefined) {
4081
+ return [2 /*return*/, /* not await */ executeAttempts(options)];
4082
+ }
4083
+ if (jokerParameterNames.length !== 0) {
4084
+ throw new UnexpectedError(spaceTrim(function (block) { return "\n JOKER parameters are not supported together with FOREACH command\n\n [\uD83E\uDDDE\u200D\u2640\uFE0F] This should be prevented in `validatePipeline`\n\n ".concat(block(pipelineIdentification), "\n "); }));
4085
+ }
4086
+ parameterValue = parameters[template.foreach.parameterName] || '';
4087
+ formatDefinition = FORMAT_DEFINITIONS.find(function (formatDefinition) {
4088
+ return __spreadArray([formatDefinition.formatName], __read((formatDefinition.aliases || [])), false).includes(template.foreach.formatName);
4089
+ });
4090
+ if (formatDefinition === undefined) {
4091
+ throw new UnexpectedError(
4092
+ // <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
4093
+ spaceTrim(function (block) { return "\n Unsupported format \"".concat(template.foreach.formatName, "\"\n\n Available formats:\n ").concat(block(FORMAT_DEFINITIONS.map(function (formatDefinition) { return formatDefinition.formatName; })
4094
+ .map(function (formatName) { return "- ".concat(formatName); })
4095
+ .join('\n')), "\n\n [\u26F7] This should never happen because format name should be validated during parsing\n\n ").concat(block(pipelineIdentification), "\n "); }));
4096
+ }
4097
+ subvalueDefinition = formatDefinition.subvalueDefinitions.find(function (subvalueDefinition) {
4098
+ return __spreadArray([subvalueDefinition.subvalueName], __read((subvalueDefinition.aliases || [])), false).includes(template.foreach.subformatName);
4099
+ });
4100
+ if (subvalueDefinition === undefined) {
4101
+ throw new UnexpectedError(
4102
+ // <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
4103
+ spaceTrim(function (block) { return "\n Unsupported subformat name \"".concat(template.foreach.subformatName, "\" for format \"").concat(template.foreach.formatName, "\"\n\n Available subformat names for format \"").concat(formatDefinition.formatName, "\":\n ").concat(block(formatDefinition.subvalueDefinitions
4104
+ .map(function (subvalueDefinition) { return subvalueDefinition.subvalueName; })
4105
+ .map(function (subvalueName) { return "- ".concat(subvalueName); })
4106
+ .join('\n')), "\n\n [\u26F7] This should never happen because subformat name should be validated during parsing\n\n ").concat(block(pipelineIdentification), "\n "); }));
4107
+ }
4108
+ if (formatDefinition.formatName === 'CSV') {
4109
+ formatSettings = settings.csvSettings;
4110
+ // <- TODO: !!!!!! More universal, make simmilar pattern for other formats for example \n vs \r\n in text
4111
+ }
4112
+ return [4 /*yield*/, subvalueDefinition.mapValues(parameterValue, formatSettings, function (subparameters, index) { return __awaiter(_this, void 0, void 0, function () {
4113
+ var mappedParameters, allSubparameters, subresultString;
4114
+ return __generator(this, function (_a) {
4115
+ switch (_a.label) {
4116
+ case 0:
4117
+ // TODO: !!!!!!! Limit to N concurrent executions
4118
+ // TODO: !!!!!!! Report progress
4119
+ try {
4120
+ mappedParameters = mapAvailableToExpectedParameters({
4121
+ expectedParameters: Object.fromEntries(template.foreach.subparameterNames.map(function (subparameterName) { return [subparameterName, null]; })),
4122
+ availableParameters: subparameters,
4123
+ });
4124
+ }
4125
+ catch (error) {
4126
+ if (!(error instanceof PipelineExecutionError)) {
4127
+ throw error;
4128
+ }
4129
+ throw new PipelineExecutionError(spaceTrim(function (block) { return "\n ".concat(error.message, "\n\n This is error in FOREACH command\n You have probbably passed wrong data to pipeline or wrong data was generated which are processed by FOREACH command\n\n ").concat(block(pipelineIdentification), "\n Subparameter index: ").concat(index, "\n "); }));
4130
+ }
4131
+ allSubparameters = __assign(__assign({}, parameters), mappedParameters);
4132
+ // Note: [👨‍👨‍👧] Now we can freeze `subparameters` because we are sure that all and only used parameters are defined and are not going to be changed
4133
+ Object.freeze(allSubparameters);
4134
+ return [4 /*yield*/, executeAttempts(__assign(__assign({}, options), { priority: priority + index, parameters: allSubparameters, pipelineIdentification: spaceTrim(function (block) { return "\n ".concat(block(pipelineIdentification), "\n Subparameter index: ").concat(index, "\n "); }) }))];
4135
+ case 1:
4136
+ subresultString = _a.sent();
4137
+ return [2 /*return*/, subresultString];
4138
+ }
4139
+ });
4140
+ }); })];
4141
+ case 1:
4142
+ resultString = _a.sent();
4143
+ return [2 /*return*/, resultString];
3876
4144
  }
3877
- return outputParameters;
4145
+ });
4146
+ });
4147
+ }
4148
+ /**
4149
+ * TODO: !!!!!! Make pipelineIdentification more precise
4150
+ * TODO: !!!!!! How FOREACH execution looks in the report
4151
+ */
4152
+
4153
+ /**
4154
+ * @@@
4155
+ *
4156
+ * @private internal utility of `createPipelineExecutor`
4157
+ */
4158
+ function getContextForTemplate(template) {
4159
+ return __awaiter(this, void 0, void 0, function () {
4160
+ return __generator(this, function (_a) {
4161
+ TODO_USE(template);
4162
+ return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [🏍] Implement */];
4163
+ });
4164
+ });
4165
+ }
4166
+
4167
+ /**
4168
+ * @@@
4169
+ *
4170
+ * @private internal utility of `createPipelineExecutor`
4171
+ */
4172
+ function getKnowledgeForTemplate(options) {
4173
+ return __awaiter(this, void 0, void 0, function () {
4174
+ var preparedPipeline, template;
4175
+ return __generator(this, function (_a) {
4176
+ preparedPipeline = options.preparedPipeline, template = options.template;
4177
+ // TODO: [♨] Implement Better - use real index and keyword search from `template` and {samples}
4178
+ TODO_USE(template);
4179
+ return [2 /*return*/, preparedPipeline.knowledgePieces.map(function (_a) {
4180
+ var content = _a.content;
4181
+ return "- ".concat(content);
4182
+ }).join('\n')];
4183
+ });
4184
+ });
4185
+ }
4186
+
4187
+ /**
4188
+ * @@@
4189
+ *
4190
+ * @private internal utility of `createPipelineExecutor`
4191
+ */
4192
+ function getSamplesForTemplate(template) {
4193
+ return __awaiter(this, void 0, void 0, function () {
4194
+ return __generator(this, function (_a) {
4195
+ // TODO: [♨] Implement Better - use real index and keyword search
4196
+ TODO_USE(template);
4197
+ return [2 /*return*/, RESERVED_PARAMETER_MISSING_VALUE /* <- TODO: [♨] Implement */];
4198
+ });
4199
+ });
4200
+ }
4201
+
4202
+ /**
4203
+ * @@@
4204
+ *
4205
+ * @private internal utility of `createPipelineExecutor`
4206
+ */
4207
+ function getReservedParametersForTemplate(options) {
4208
+ return __awaiter(this, void 0, void 0, function () {
4209
+ var preparedPipeline, template, pipelineIdentification, context, knowledge, samples, currentDate, modelName, reservedParameters, _loop_1, RESERVED_PARAMETER_NAMES_1, RESERVED_PARAMETER_NAMES_1_1, parameterName;
4210
+ var e_1, _a;
4211
+ return __generator(this, function (_b) {
4212
+ switch (_b.label) {
4213
+ case 0:
4214
+ preparedPipeline = options.preparedPipeline, template = options.template, pipelineIdentification = options.pipelineIdentification;
4215
+ return [4 /*yield*/, getContextForTemplate(template)];
4216
+ case 1:
4217
+ context = _b.sent();
4218
+ return [4 /*yield*/, getKnowledgeForTemplate({ preparedPipeline: preparedPipeline, template: template })];
4219
+ case 2:
4220
+ knowledge = _b.sent();
4221
+ return [4 /*yield*/, getSamplesForTemplate(template)];
4222
+ case 3:
4223
+ samples = _b.sent();
4224
+ currentDate = new Date().toISOString();
4225
+ modelName = RESERVED_PARAMETER_MISSING_VALUE;
4226
+ reservedParameters = {
4227
+ content: RESERVED_PARAMETER_RESTRICTED,
4228
+ context: context,
4229
+ knowledge: knowledge,
4230
+ samples: samples,
4231
+ currentDate: currentDate,
4232
+ modelName: modelName,
4233
+ };
4234
+ _loop_1 = function (parameterName) {
4235
+ if (reservedParameters[parameterName] === undefined) {
4236
+ throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Reserved parameter {".concat(parameterName, "} is not defined\n\n ").concat(block(pipelineIdentification), "\n "); }));
4237
+ }
4238
+ };
4239
+ try {
4240
+ // Note: Doublecheck that ALL reserved parameters are defined:
4241
+ for (RESERVED_PARAMETER_NAMES_1 = __values(RESERVED_PARAMETER_NAMES), RESERVED_PARAMETER_NAMES_1_1 = RESERVED_PARAMETER_NAMES_1.next(); !RESERVED_PARAMETER_NAMES_1_1.done; RESERVED_PARAMETER_NAMES_1_1 = RESERVED_PARAMETER_NAMES_1.next()) {
4242
+ parameterName = RESERVED_PARAMETER_NAMES_1_1.value;
4243
+ _loop_1(parameterName);
4244
+ }
4245
+ }
4246
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
4247
+ finally {
4248
+ try {
4249
+ if (RESERVED_PARAMETER_NAMES_1_1 && !RESERVED_PARAMETER_NAMES_1_1.done && (_a = RESERVED_PARAMETER_NAMES_1.return)) _a.call(RESERVED_PARAMETER_NAMES_1);
4250
+ }
4251
+ finally { if (e_1) throw e_1.error; }
4252
+ }
4253
+ return [2 /*return*/, reservedParameters];
4254
+ }
4255
+ });
4256
+ });
4257
+ }
4258
+
4259
+ /**
4260
+ * @@@
4261
+ *
4262
+ * @private internal utility of `createPipelineExecutor`
4263
+ */
4264
+ function executeTemplate(options) {
4265
+ return __awaiter(this, void 0, void 0, function () {
4266
+ 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;
4267
+ var e_1, _f, _g;
4268
+ return __generator(this, function (_h) {
4269
+ switch (_h.label) {
4270
+ case 0:
4271
+ 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;
4272
+ maxExecutionAttempts = settings.maxExecutionAttempts;
4273
+ name = "pipeline-executor-frame-".concat(currentTemplate.name);
4274
+ title = currentTemplate.title;
4275
+ priority = preparedPipeline.templates.length - preparedPipeline.templates.indexOf(currentTemplate);
4276
+ return [4 /*yield*/, onProgress({
4277
+ name: name,
4278
+ title: title,
4279
+ isStarted: false,
4280
+ isDone: false,
4281
+ templateType: currentTemplate.templateType,
4282
+ parameterName: currentTemplate.resultingParameterName,
4283
+ parameterValue: null,
4284
+ // <- [🍸]
4285
+ })];
4286
+ case 1:
4287
+ _h.sent();
4288
+ usedParameterNames = extractParameterNamesFromTemplate(currentTemplate);
4289
+ dependentParameterNames = new Set(currentTemplate.dependentParameterNames);
4290
+ // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
4291
+ if (union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)).size !== 0) {
4292
+ throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Dependent parameters are not consistent with used parameters:\n\n Dependent parameters:\n ".concat(Array.from(dependentParameterNames)
4293
+ .map(function (name) { return "{".concat(name, "}"); })
4294
+ .join(', '), "\n\n Used parameters:\n ").concat(Array.from(usedParameterNames)
4295
+ .map(function (name) { return "{".concat(name, "}"); })
4296
+ .join(', '), "\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
4297
+ }
4298
+ _b = (_a = Object).freeze;
4299
+ _c = [{}];
4300
+ return [4 /*yield*/, getReservedParametersForTemplate({
4301
+ preparedPipeline: preparedPipeline,
4302
+ template: currentTemplate,
4303
+ pipelineIdentification: pipelineIdentification,
4304
+ })];
4305
+ case 2:
4306
+ definedParameters = _b.apply(_a, [__assign.apply(void 0, [__assign.apply(void 0, _c.concat([(_h.sent())])), parametersToPass])]);
4307
+ definedParameterNames = new Set(Object.keys(definedParameters));
4308
+ parameters = {};
4309
+ _loop_1 = function (parameterName) {
4310
+ // Situation: Parameter is defined and used
4311
+ if (definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
4312
+ parameters[parameterName] = definedParameters[parameterName];
4313
+ }
4314
+ // Situation: Parameter is defined but NOT used
4315
+ else if (definedParameterNames.has(parameterName) && !usedParameterNames.has(parameterName)) ;
4316
+ // Situation: Parameter is NOT defined BUT used
4317
+ else if (!definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
4318
+ // Houston, we have a problem
4319
+ // Note: Checking part is also done in `validatePipeline`, but it’s good to doublecheck
4320
+ throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Parameter {".concat(parameterName, "} is NOT defined\n BUT used in template \"").concat(currentTemplate.title || currentTemplate.name, "\"\n\n This should be catched in `validatePipeline`\n\n ").concat(block(pipelineIdentification), "\n\n "); }));
4321
+ }
4322
+ };
4323
+ try {
4324
+ // Note: [2] Check that all used parameters are defined and removing unused parameters for this template
4325
+ // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
4326
+ for (_d = __values(Array.from(union(definedParameterNames, usedParameterNames, dependentParameterNames))), _e = _d.next(); !_e.done; _e = _d.next()) {
4327
+ parameterName = _e.value;
4328
+ _loop_1(parameterName);
4329
+ }
4330
+ }
4331
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
4332
+ finally {
4333
+ try {
4334
+ if (_e && !_e.done && (_f = _d.return)) _f.call(_d);
4335
+ }
4336
+ finally { if (e_1) throw e_1.error; }
4337
+ }
4338
+ // Note: [👨‍👨‍👧] Now we can freeze `parameters` because we are sure that all and only used parameters are defined and are not going to be changed
4339
+ Object.freeze(parameters);
4340
+ maxAttempts = currentTemplate.templateType === 'DIALOG_TEMPLATE' ? Infinity : maxExecutionAttempts;
4341
+ jokerParameterNames = currentTemplate.jokerParameterNames || [];
4342
+ preparedContent = (currentTemplate.preparedContent || '{content}')
4343
+ .split('{content}')
4344
+ .join(currentTemplate.content);
4345
+ return [4 /*yield*/, executeFormatCells({
4346
+ jokerParameterNames: jokerParameterNames,
4347
+ priority: priority,
4348
+ maxAttempts: maxAttempts,
4349
+ preparedContent: preparedContent,
4350
+ parameters: parameters,
4351
+ template: currentTemplate,
4352
+ preparedPipeline: preparedPipeline,
4353
+ tools: tools,
4354
+ llmTools: llmTools,
4355
+ settings: settings,
4356
+ $executionReport: $executionReport,
4357
+ pipelineIdentification: pipelineIdentification,
4358
+ })];
4359
+ case 3:
4360
+ resultString = _h.sent();
4361
+ return [4 /*yield*/, onProgress({
4362
+ name: name,
4363
+ title: title,
4364
+ isStarted: true,
4365
+ isDone: true,
4366
+ templateType: currentTemplate.templateType,
4367
+ parameterName: currentTemplate.resultingParameterName,
4368
+ parameterValue: resultString,
4369
+ // <- [🍸]
4370
+ })];
4371
+ case 4:
4372
+ _h.sent();
4373
+ return [2 /*return*/, Object.freeze((_g = {},
4374
+ _g[currentTemplate.resultingParameterName] =
4375
+ // <- Note: [👩‍👩‍👧] No need to detect parameter collision here because pipeline checks logic consistency during construction
4376
+ resultString,
4377
+ _g))];
4378
+ }
4379
+ });
4380
+ });
4381
+ }
4382
+ /**
4383
+ * TODO: [🤹‍♂️]
4384
+ */
4385
+
4386
+ /**
4387
+ * @@@
4388
+ *
4389
+ * @private internal utility of `createPipelineExecutor`
4390
+ */
4391
+ function filterJustOutputParameters(options) {
4392
+ var e_1, _a;
4393
+ var preparedPipeline = options.preparedPipeline, parametersToPass = options.parametersToPass, $warnings = options.$warnings, pipelineIdentification = options.pipelineIdentification;
4394
+ var outputParameters = {};
4395
+ var _loop_1 = function (parameter) {
4396
+ if (parametersToPass[parameter.name] === undefined) {
4397
+ // [4]
4398
+ $warnings.push(new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Parameter {".concat(parameter.name, "} should be an output parameter, but it was not generated during pipeline execution\n\n ").concat(block(pipelineIdentification), "\n "); })));
4399
+ return "continue";
3878
4400
  }
3879
- var errors, warnings, executionReport, isReturned, _a, _b, parameter, e_1_1, _loop_1, _c, _d, parameterName, state_1, e_2_1, parametersToPass, resovedParameterNames_1, unresovedTemplates_1, resolving_1, loopLimit, _loop_2, error_1, usage_1, outputParameters_1, usage, outputParameters;
4401
+ outputParameters[parameter.name] = parametersToPass[parameter.name] || '';
4402
+ };
4403
+ try {
4404
+ // Note: Filter ONLY output parameters
4405
+ // TODO: [👩🏾‍🤝‍👩🏻] Maybe use here `mapAvailableToExpectedParameters`
4406
+ for (var _b = __values(preparedPipeline.parameters.filter(function (_a) {
4407
+ var isOutput = _a.isOutput;
4408
+ return isOutput;
4409
+ })), _c = _b.next(); !_c.done; _c = _b.next()) {
4410
+ var parameter = _c.value;
4411
+ _loop_1(parameter);
4412
+ }
4413
+ }
4414
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
4415
+ finally {
4416
+ try {
4417
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
4418
+ }
4419
+ finally { if (e_1) throw e_1.error; }
4420
+ }
4421
+ return outputParameters;
4422
+ }
4423
+
4424
+ /**
4425
+ * @@@
4426
+ *
4427
+ * Note: This is not a `PipelineExecutor` (which is binded with one exact pipeline), but a utility function of `createPipelineExecutor` which creates `PipelineExecutor`
4428
+ *
4429
+ * @private internal utility of `createPipelineExecutor`
4430
+ */
4431
+ function executePipeline(options) {
4432
+ return __awaiter(this, void 0, void 0, function () {
4433
+ var inputParameters, tools, onProgress, pipeline, setPreparedPipeline, pipelineIdentification, settings, maxParallelCount, isVerbose, preparedPipeline, llmTools, errors, warnings, executionReport, isReturned, _a, _b, parameter, e_1_1, _loop_1, _c, _d, parameterName, state_1, e_2_1, parametersToPass, resovedParameterNames_1, unresovedTemplates_1, resolving_1, loopLimit, _loop_2, error_1, usage_1, outputParameters_1, usage, outputParameters;
3880
4434
  var e_1, _e, e_2, _f;
3881
4435
  return __generator(this, function (_g) {
3882
4436
  switch (_g.label) {
3883
4437
  case 0:
4438
+ inputParameters = options.inputParameters, tools = options.tools, onProgress = options.onProgress, pipeline = options.pipeline, setPreparedPipeline = options.setPreparedPipeline, pipelineIdentification = options.pipelineIdentification, settings = options.settings;
4439
+ maxParallelCount = settings.maxParallelCount, isVerbose = settings.isVerbose;
4440
+ preparedPipeline = options.preparedPipeline;
4441
+ llmTools = joinLlmExecutionTools.apply(void 0, __spreadArray([], __read(arrayableToArray(tools.llm)), false));
3884
4442
  if (!(preparedPipeline === undefined)) return [3 /*break*/, 2];
3885
4443
  return [4 /*yield*/, preparePipeline(pipeline, {
3886
4444
  llmTools: llmTools,
@@ -3889,6 +4447,7 @@ function createPipelineExecutor(options) {
3889
4447
  })];
3890
4448
  case 1:
3891
4449
  preparedPipeline = _g.sent();
4450
+ setPreparedPipeline(preparedPipeline);
3892
4451
  _g.label = 2;
3893
4452
  case 2:
3894
4453
  errors = [];
@@ -3958,7 +4517,7 @@ function createPipelineExecutor(options) {
3958
4517
  return name === parameterName;
3959
4518
  });
3960
4519
  if (!(parameter === undefined)) return [3 /*break*/, 1];
3961
- warnings.push(new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Extra parameter {".concat(parameterName, "} is being passed which is not part of the pipeline.\n\n ").concat(block(pipelineIdentification), "\n "); })));
4520
+ warnings.push(new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Extra parameter {".concat(parameterName, "} is being passed which is not part of the pipeline.\n\n ").concat(block(pipelineIdentification), "\n "); })));
3962
4521
  return [3 /*break*/, 4];
3963
4522
  case 1:
3964
4523
  if (!(parameter.isInput === false)) return [3 /*break*/, 4];
@@ -3970,10 +4529,10 @@ function createPipelineExecutor(options) {
3970
4529
  // Note: Wait a short time to prevent race conditions
3971
4530
  _h.sent();
3972
4531
  _h.label = 3;
3973
- case 3: return [2 /*return*/, { value: $asDeeplyFrozenSerializableJson(spaceTrim$1(function (block) { return "\n Unuccessful PipelineExecutorResult (with extra parameter {".concat(parameter.name, "}) PipelineExecutorResult\n\n ").concat(block(pipelineIdentification), "\n "); }), {
4532
+ case 3: return [2 /*return*/, { value: $asDeeplyFrozenSerializableJson(spaceTrim$1(function (block) { return "\n Unuccessful PipelineExecutorResult (with extra parameter {".concat(parameter.name, "}) PipelineExecutorResult\n\n ").concat(block(pipelineIdentification), "\n "); }), {
3974
4533
  isSuccessful: false,
3975
4534
  errors: __spreadArray([
3976
- new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Parameter {".concat(parameter.name, "} is passed as input parameter but it is not input\n\n ").concat(block(pipelineIdentification), "\n "); }))
4535
+ new PipelineExecutionError(spaceTrim$1(function (block) { return "\n Parameter {".concat(parameter.name, "} is passed as input parameter but it is not input\n\n ").concat(block(pipelineIdentification), "\n "); }))
3977
4536
  ], __read(errors), false).map(serializeError),
3978
4537
  warnings: warnings.map(serializeError),
3979
4538
  executionReport: executionReport,
@@ -4037,7 +4596,7 @@ function createPipelineExecutor(options) {
4037
4596
  case 0:
4038
4597
  if (loopLimit-- < 0) {
4039
4598
  // Note: Really UnexpectedError not LimitReachedError - this should be catched during validatePipeline
4040
- throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Loop limit reached during resolving parameters pipeline execution\n\n ".concat(block(pipelineIdentification), "\n "); }));
4599
+ throw new UnexpectedError(spaceTrim$1(function (block) { return "\n Loop limit reached during resolving parameters pipeline execution\n\n ".concat(block(pipelineIdentification), "\n "); }));
4041
4600
  }
4042
4601
  currentTemplate = unresovedTemplates_1.find(function (template) {
4043
4602
  return template.dependentParameterNames.every(function (name) {
@@ -4047,29 +4606,52 @@ function createPipelineExecutor(options) {
4047
4606
  if (!(!currentTemplate && resolving_1.length === 0)) return [3 /*break*/, 1];
4048
4607
  throw new UnexpectedError(
4049
4608
  // TODO: [🐎] DRY
4050
- spaceTrim$1(function (block) { return "\n Can not resolve some parameters:\n\n ".concat(block(pipelineIdentification), "\n\n Can not resolve:\n ").concat(block(unresovedTemplates_1
4609
+ spaceTrim$1(function (block) { return "\n Can not resolve some parameters:\n\n ".concat(block(pipelineIdentification), "\n\n Can not resolve:\n ").concat(block(unresovedTemplates_1
4051
4610
  .map(function (_a) {
4052
4611
  var resultingParameterName = _a.resultingParameterName, dependentParameterNames = _a.dependentParameterNames;
4053
4612
  return "- Parameter {".concat(resultingParameterName, "} which depends on ").concat(dependentParameterNames
4054
4613
  .map(function (dependentParameterName) { return "{".concat(dependentParameterName, "}"); })
4055
4614
  .join(' and '));
4056
4615
  })
4057
- .join('\n')), "\n\n Resolved:\n ").concat(block(resovedParameterNames_1.map(function (name) { return "- Parameter {".concat(name, "}"); }).join('\n')), "\n\n Note: This should be catched in `validatePipeline`\n "); }));
4616
+ .join('\n')), "\n\n Resolved:\n ").concat(block(resovedParameterNames_1.map(function (name) { return "- Parameter {".concat(name, "}"); }).join('\n')), "\n\n Note: This should be catched in `validatePipeline`\n "); }));
4058
4617
  case 1:
4059
4618
  if (!!currentTemplate) return [3 /*break*/, 3];
4060
- /* [5] */ return [4 /*yield*/, Promise.race(resolving_1)];
4619
+ /* [🤹‍♂️] */ return [4 /*yield*/, Promise.race(resolving_1)];
4061
4620
  case 2:
4062
- /* [5] */ _j.sent();
4621
+ /* [🤹‍♂️] */ _j.sent();
4063
4622
  return [3 /*break*/, 4];
4064
4623
  case 3:
4065
4624
  unresovedTemplates_1 = unresovedTemplates_1.filter(function (template) { return template !== currentTemplate; });
4066
- work_1 = executeSingleTemplate(currentTemplate)
4067
- .then(function () {
4625
+ work_1 = executeTemplate({
4626
+ currentTemplate: currentTemplate,
4627
+ preparedPipeline: preparedPipeline,
4628
+ parametersToPass: parametersToPass,
4629
+ tools: tools,
4630
+ llmTools: llmTools,
4631
+ onProgress: function (progress) {
4632
+ if (isReturned) {
4633
+ 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)
4634
+ .split('\n')
4635
+ .map(function (line) { return "> ".concat(line); })
4636
+ .join('\n')), "\n "); }));
4637
+ }
4638
+ if (onProgress) {
4639
+ onProgress(progress);
4640
+ }
4641
+ },
4642
+ settings: settings,
4643
+ $executionReport: executionReport,
4644
+ pipelineIdentification: spaceTrim$1(function (block) { return "\n ".concat(block(pipelineIdentification), "\n Template name: ").concat(currentTemplate.name, "\n Template title: ").concat(currentTemplate.title, "\n "); }),
4645
+ })
4646
+ .then(function (newParametersToPass) {
4647
+ parametersToPass = __assign(__assign({}, newParametersToPass), parametersToPass);
4068
4648
  resovedParameterNames_1 = __spreadArray(__spreadArray([], __read(resovedParameterNames_1), false), [currentTemplate.resultingParameterName], false);
4069
4649
  })
4070
4650
  .then(function () {
4071
4651
  resolving_1 = resolving_1.filter(function (w) { return w !== work_1; });
4072
4652
  });
4653
+ // <- Note: Errors are catched here [3]
4654
+ // TODO: BUT if in multiple templates are errors, only the first one is catched so maybe we should catch errors here and save them to errors array here
4073
4655
  resolving_1.push(work_1);
4074
4656
  _j.label = 4;
4075
4657
  case 4: return [2 /*return*/];
@@ -4096,7 +4678,12 @@ function createPipelineExecutor(options) {
4096
4678
  var result = _a.result;
4097
4679
  return (result === null || result === void 0 ? void 0 : result.usage) || ZERO_USAGE;
4098
4680
  })), false));
4099
- outputParameters_1 = filterJustOutputParameters();
4681
+ outputParameters_1 = filterJustOutputParameters({
4682
+ preparedPipeline: preparedPipeline,
4683
+ parametersToPass: parametersToPass,
4684
+ $warnings: warnings,
4685
+ pipelineIdentification: pipelineIdentification,
4686
+ });
4100
4687
  isReturned = true;
4101
4688
  if (!(onProgress !== undefined)) return [3 /*break*/, 27];
4102
4689
  // Note: Wait a short time to prevent race conditions
@@ -4119,7 +4706,12 @@ function createPipelineExecutor(options) {
4119
4706
  var result = _a.result;
4120
4707
  return (result === null || result === void 0 ? void 0 : result.usage) || ZERO_USAGE;
4121
4708
  })), false));
4122
- outputParameters = filterJustOutputParameters();
4709
+ outputParameters = filterJustOutputParameters({
4710
+ preparedPipeline: preparedPipeline,
4711
+ parametersToPass: parametersToPass,
4712
+ $warnings: warnings,
4713
+ pipelineIdentification: pipelineIdentification,
4714
+ });
4123
4715
  isReturned = true;
4124
4716
  if (!(onProgress !== undefined)) return [3 /*break*/, 30];
4125
4717
  // Note: Wait a short time to prevent race conditions
@@ -4139,22 +4731,65 @@ function createPipelineExecutor(options) {
4139
4731
  })];
4140
4732
  }
4141
4733
  });
4142
- }); };
4143
- return pipelineExecutor;
4734
+ });
4144
4735
  }
4736
+
4145
4737
  /**
4146
- * TODO:[main] !!! Identify not only pipeline BUT exact template ${block(pipelineIdentification)}
4147
- * TODO: Use isVerbose here (not only pass to `preparePipeline`)
4148
- * TODO: [🧠][🌳] Use here `countTotalUsage` and put preparation and prepared pipiline to report
4149
- * TODO: [🪂] Use maxParallelCount here (not only pass to `preparePipeline`)
4150
- * TODO: [♈] Probbably move expectations from templates to parameters
4151
- * TODO: [🧠] When not meet expectations in DIALOG_TEMPLATE, make some way to tell the user
4152
- * TODO: [👧] Strongly type the executors to avoid need of remove nullables whtn noUncheckedIndexedAccess in tsconfig.json
4153
- * Note: CreatePipelineExecutorOptions are just connected to PipelineExecutor so do not extract to types folder
4154
- * TODO: [🧠][3] transparent = (report intermediate parameters) / opaque execution = (report only output parameters) progress reporting mode
4155
- * TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
4156
- * TODO: [🧠][💷] `assertsExecutionSuccessful` should be the method of `PipelineExecutor` result BUT maybe NOT to preserve pure JSON object
4738
+ * Creates executor function from pipeline and execution tools.
4739
+ *
4740
+ * @returns The executor function
4741
+ * @throws {PipelineLogicError} on logical error in the pipeline
4742
+ * @public exported from `@promptbook/core`
4157
4743
  */
4744
+ function createPipelineExecutor(options) {
4745
+ var _this = this;
4746
+ var pipeline = options.pipeline, tools = options.tools, _a = options.settings, settings = _a === void 0 ? {} : _a;
4747
+ var _b = settings.maxExecutionAttempts, maxExecutionAttempts = _b === void 0 ? MAX_EXECUTION_ATTEMPTS : _b, _c = settings.maxParallelCount, maxParallelCount = _c === void 0 ? MAX_PARALLEL_COUNT : _c, _d = settings.csvSettings, csvSettings = _d === void 0 ? DEFAULT_CSV_SETTINGS : _d, _e = settings.isVerbose, isVerbose = _e === void 0 ? IS_VERBOSE : _e, _f = settings.isNotPreparedWarningSupressed, isNotPreparedWarningSupressed = _f === void 0 ? false : _f;
4748
+ validatePipeline(pipeline);
4749
+ var pipelineIdentification = (function () {
4750
+ // Note: This is a 😐 implementation of [🚞]
4751
+ var _ = [];
4752
+ if (pipeline.sourceFile !== undefined) {
4753
+ _.push("File: ".concat(pipeline.sourceFile));
4754
+ }
4755
+ if (pipeline.pipelineUrl !== undefined) {
4756
+ _.push("Url: ".concat(pipeline.pipelineUrl));
4757
+ }
4758
+ return _.join('\n');
4759
+ })();
4760
+ var preparedPipeline;
4761
+ if (isPipelinePrepared(pipeline)) {
4762
+ preparedPipeline = pipeline;
4763
+ }
4764
+ else if (isNotPreparedWarningSupressed !== true) {
4765
+ console.warn(spaceTrim$1(function (block) { return "\n Pipeline is not prepared\n\n ".concat(block(pipelineIdentification), "\n\n It will be prepared ad-hoc before the first execution and **returned as `preparedPipeline` in `PipelineExecutorResult`**\n But it is recommended to prepare the pipeline during collection preparation\n\n @see more at https://ptbk.io/prepare-pipeline\n "); }));
4766
+ }
4767
+ var runCount = 0;
4768
+ var pipelineExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
4769
+ return __generator(this, function (_a) {
4770
+ runCount++;
4771
+ return [2 /*return*/, /* not await */ executePipeline({
4772
+ pipeline: pipeline,
4773
+ preparedPipeline: preparedPipeline,
4774
+ setPreparedPipeline: function (newPreparedPipeline) {
4775
+ preparedPipeline = newPreparedPipeline;
4776
+ },
4777
+ inputParameters: inputParameters,
4778
+ tools: tools,
4779
+ onProgress: onProgress,
4780
+ pipelineIdentification: spaceTrim$1(function (block) { return "\n ".concat(block(pipelineIdentification), "\n ").concat(runCount === 1 ? '' : "Run #".concat(runCount), "\n "); }),
4781
+ settings: {
4782
+ maxExecutionAttempts: maxExecutionAttempts,
4783
+ maxParallelCount: maxParallelCount,
4784
+ csvSettings: csvSettings,
4785
+ isVerbose: isVerbose,
4786
+ isNotPreparedWarningSupressed: isNotPreparedWarningSupressed,
4787
+ },
4788
+ })];
4789
+ });
4790
+ }); };
4791
+ return pipelineExecutor;
4792
+ }
4158
4793
 
4159
4794
  /**
4160
4795
  * @@@
@@ -4264,8 +4899,13 @@ function prepareKnowledgeFromMarkdown(knowledgeContent /* <- TODO: [🖖] (?mayb
4264
4899
  case 6: return [3 /*break*/, 8];
4265
4900
  case 7:
4266
4901
  error_1 = _c.sent();
4902
+ // Note: Here is expected error:
4903
+ // > PipelineExecutionError: You have not provided any `LlmExecutionTools` that support model variant "EMBEDDING
4904
+ if (!(error_1 instanceof PipelineExecutionError)) {
4905
+ throw error_1;
4906
+ }
4267
4907
  // TODO: [🟥] Detect browser / node and make it colorfull
4268
- console.error(error_1);
4908
+ console.error(error_1, "<- Note: This error is not critical to prepare the pipeline, just knowledge pieces won't have embeddings");
4269
4909
  return [3 /*break*/, 8];
4270
4910
  case 8: return [2 /*return*/, {
4271
4911
  name: name,
@@ -5172,53 +5812,288 @@ var expectCommandParser = {
5172
5812
  if (!(error instanceof Error)) {
5173
5813
  throw error;
5174
5814
  }
5175
- throw new ParseError(spaceTrim(function (block) {
5176
- return "\n Invalid FORMAT command\n ".concat(block(error.message), ":\n ");
5177
- }));
5815
+ throw new ParseError(spaceTrim(function (block) {
5816
+ return "\n Invalid FORMAT command\n ".concat(block(error.message), ":\n ");
5817
+ }));
5818
+ }
5819
+ },
5820
+ /**
5821
+ * Apply the FORMAT command to the `pipelineJson`
5822
+ *
5823
+ * Note: `$` is used to indicate that this function mutates given `templateJson`
5824
+ */
5825
+ $applyToTemplateJson: function (command, $templateJson) {
5826
+ // eslint-disable-next-line no-case-declarations
5827
+ var unit = command.unit.toLowerCase();
5828
+ $templateJson.expectations = $templateJson.expectations || {};
5829
+ $templateJson.expectations[unit] = $templateJson.expectations[unit] || {};
5830
+ if (command.sign === 'MINIMUM' || command.sign === 'EXACTLY') {
5831
+ if ($templateJson.expectations[unit].min !== undefined) {
5832
+ throw new ParseError("Already defined minumum ".concat($templateJson.expectations[unit].min, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
5833
+ }
5834
+ $templateJson.expectations[unit].min = command.amount;
5835
+ } /* not else */
5836
+ if (command.sign === 'MAXIMUM' || command.sign === 'EXACTLY') {
5837
+ if ($templateJson.expectations[unit].max !== undefined) {
5838
+ throw new ParseError("Already defined maximum ".concat($templateJson.expectations[unit].max, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
5839
+ }
5840
+ $templateJson.expectations[unit].max = command.amount;
5841
+ }
5842
+ },
5843
+ /**
5844
+ * Converts the FORMAT command back to string
5845
+ *
5846
+ * Note: This is used in `pipelineJsonToString` utility
5847
+ */
5848
+ stringify: function (command) {
5849
+ keepUnused(command);
5850
+ return "---"; // <- TODO: [🛋] Implement
5851
+ },
5852
+ /**
5853
+ * Reads the FORMAT command from the `TemplateJson`
5854
+ *
5855
+ * Note: This is used in `pipelineJsonToString` utility
5856
+ */
5857
+ takeFromTemplateJson: function ($templateJson) {
5858
+ keepUnused($templateJson);
5859
+ throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
5860
+ },
5861
+ };
5862
+
5863
+ /**
5864
+ * @@@
5865
+ *
5866
+ * @param text @@@
5867
+ * @returns @@@
5868
+ * @example 'HELLO_WORLD'
5869
+ * @example 'I_LOVE_PROMPTBOOK'
5870
+ * @public exported from `@promptbook/utils`
5871
+ */
5872
+ function normalizeTo_SCREAMING_CASE(text) {
5873
+ var e_1, _a;
5874
+ var charType;
5875
+ var lastCharType = 'OTHER';
5876
+ var normalizedName = '';
5877
+ try {
5878
+ for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
5879
+ var char = text_1_1.value;
5880
+ var normalizedChar = void 0;
5881
+ if (/^[a-z]$/.test(char)) {
5882
+ charType = 'LOWERCASE';
5883
+ normalizedChar = char.toUpperCase();
5884
+ }
5885
+ else if (/^[A-Z]$/.test(char)) {
5886
+ charType = 'UPPERCASE';
5887
+ normalizedChar = char;
5888
+ }
5889
+ else if (/^[0-9]$/.test(char)) {
5890
+ charType = 'NUMBER';
5891
+ normalizedChar = char;
5892
+ }
5893
+ else if (/^\/$/.test(char)) {
5894
+ charType = 'SLASH';
5895
+ normalizedChar = char;
5896
+ }
5897
+ else {
5898
+ charType = 'OTHER';
5899
+ normalizedChar = '_';
5900
+ }
5901
+ if (charType !== lastCharType &&
5902
+ !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
5903
+ !(lastCharType === 'NUMBER') &&
5904
+ !(charType === 'NUMBER')) {
5905
+ normalizedName += '_';
5906
+ }
5907
+ normalizedName += normalizedChar;
5908
+ lastCharType = charType;
5909
+ }
5910
+ }
5911
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
5912
+ finally {
5913
+ try {
5914
+ if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
5915
+ }
5916
+ finally { if (e_1) throw e_1.error; }
5917
+ }
5918
+ normalizedName = normalizedName.replace(/_+/g, '_');
5919
+ normalizedName = normalizedName.replace(/_?\/_?/g, '/');
5920
+ normalizedName = normalizedName.replace(/^_/, '');
5921
+ normalizedName = normalizedName.replace(/_$/, '');
5922
+ return normalizedName;
5923
+ }
5924
+ /**
5925
+ * TODO: Tests
5926
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'Moje tabule' })).toEqual('/VtG7sR9rRJqwNEdM2/Moje tabule');
5927
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'ěščřžžýáíúů' })).toEqual('/VtG7sR9rRJqwNEdM2/escrzyaieuu');
5928
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj');
5929
+ * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj_ahojAhoj ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj-ahoj-ahoj-ahoj');
5930
+ * TODO: [🌺] Use some intermediate util splitWords
5931
+ */
5932
+
5933
+ /**
5934
+ * @@@
5935
+ *
5936
+ * @param text @@@
5937
+ * @param _isFirstLetterCapital @@@
5938
+ * @returns @@@
5939
+ * @example 'helloWorld'
5940
+ * @example 'iLovePromptbook'
5941
+ * @public exported from `@promptbook/utils`
5942
+ */
5943
+ function normalizeTo_camelCase(text, _isFirstLetterCapital) {
5944
+ var e_1, _a;
5945
+ if (_isFirstLetterCapital === void 0) { _isFirstLetterCapital = false; }
5946
+ var charType;
5947
+ var lastCharType = null;
5948
+ var normalizedName = '';
5949
+ try {
5950
+ for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
5951
+ var char = text_1_1.value;
5952
+ var normalizedChar = void 0;
5953
+ if (/^[a-z]$/.test(char)) {
5954
+ charType = 'LOWERCASE';
5955
+ normalizedChar = char;
5956
+ }
5957
+ else if (/^[A-Z]$/.test(char)) {
5958
+ charType = 'UPPERCASE';
5959
+ normalizedChar = char.toLowerCase();
5960
+ }
5961
+ else if (/^[0-9]$/.test(char)) {
5962
+ charType = 'NUMBER';
5963
+ normalizedChar = char;
5964
+ }
5965
+ else {
5966
+ charType = 'OTHER';
5967
+ normalizedChar = '';
5968
+ }
5969
+ if (!lastCharType) {
5970
+ if (_isFirstLetterCapital) {
5971
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
5972
+ }
5973
+ }
5974
+ else if (charType !== lastCharType &&
5975
+ !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
5976
+ !(lastCharType === 'NUMBER') &&
5977
+ !(charType === 'NUMBER')) {
5978
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
5979
+ }
5980
+ normalizedName += normalizedChar;
5981
+ lastCharType = charType;
5982
+ }
5983
+ }
5984
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
5985
+ finally {
5986
+ try {
5987
+ if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
5988
+ }
5989
+ finally { if (e_1) throw e_1.error; }
5990
+ }
5991
+ return normalizedName;
5992
+ }
5993
+ /**
5994
+ * TODO: [🌺] Use some intermediate util splitWords
5995
+ */
5996
+
5997
+ /**
5998
+ * Removes quotes from a string
5999
+ *
6000
+ * Tip: This is very usefull for post-processing of the result of the LLM model
6001
+ * Note: This function removes only the same quotes from the beginning and the end of the string
6002
+ * Note: There are two simmilar functions:
6003
+ * - `removeQuotes` which removes only bounding quotes
6004
+ * - `unwrapResult` which removes whole introduce sentence
6005
+ *
6006
+ * @param text optionally quoted text
6007
+ * @returns text without quotes
6008
+ * @public exported from `@promptbook/utils`
6009
+ */
6010
+ function removeQuotes(text) {
6011
+ if (text.startsWith('"') && text.endsWith('"')) {
6012
+ return text.slice(1, -1);
6013
+ }
6014
+ if (text.startsWith('\'') && text.endsWith('\'')) {
6015
+ return text.slice(1, -1);
6016
+ }
6017
+ return text;
6018
+ }
6019
+
6020
+ /**
6021
+ * Function `validateParameterName` will @@@
6022
+ *
6023
+ * @param parameterName @@@
6024
+ * @returns @@@
6025
+ * @throws {ParseError} @@@
6026
+ * @private within the repository
6027
+ */
6028
+ function validateParameterName(parameterName) {
6029
+ var e_1, _a;
6030
+ var rawParameterName = parameterName;
6031
+ try {
6032
+ for (var _b = __values([
6033
+ ['`', '`'],
6034
+ ['{', '}'],
6035
+ ['[', ']'],
6036
+ ['(', ')'],
6037
+ ['<', '>'],
6038
+ ]), _c = _b.next(); !_c.done; _c = _b.next()) {
6039
+ var _d = __read(_c.value, 2), start = _d[0], end = _d[1];
6040
+ if (parameterName.substring(0, 1) === start &&
6041
+ parameterName.substring(parameterName.length - 1, parameterName.length) === end
6042
+ // <- TODO: More universal that 1 character
6043
+ ) {
6044
+ parameterName = parameterName.substring(1, parameterName.length - 1);
6045
+ // <- TODO: More universal that 1 character
6046
+ }
5178
6047
  }
5179
- },
5180
- /**
5181
- * Apply the FORMAT command to the `pipelineJson`
5182
- *
5183
- * Note: `$` is used to indicate that this function mutates given `templateJson`
5184
- */
5185
- $applyToTemplateJson: function (command, $templateJson) {
5186
- // eslint-disable-next-line no-case-declarations
5187
- var unit = command.unit.toLowerCase();
5188
- $templateJson.expectations = $templateJson.expectations || {};
5189
- $templateJson.expectations[unit] = $templateJson.expectations[unit] || {};
5190
- if (command.sign === 'MINIMUM' || command.sign === 'EXACTLY') {
5191
- if ($templateJson.expectations[unit].min !== undefined) {
5192
- throw new ParseError("Already defined minumum ".concat($templateJson.expectations[unit].min, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
5193
- }
5194
- $templateJson.expectations[unit].min = command.amount;
5195
- } /* not else */
5196
- if (command.sign === 'MAXIMUM' || command.sign === 'EXACTLY') {
5197
- if ($templateJson.expectations[unit].max !== undefined) {
5198
- throw new ParseError("Already defined maximum ".concat($templateJson.expectations[unit].max, " ").concat(command.unit.toLowerCase(), ", now trying to redefine it to ").concat(command.amount));
5199
- }
5200
- $templateJson.expectations[unit].max = command.amount;
6048
+ }
6049
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
6050
+ finally {
6051
+ try {
6052
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
5201
6053
  }
5202
- },
5203
- /**
5204
- * Converts the FORMAT command back to string
5205
- *
5206
- * Note: This is used in `pipelineJsonToString` utility
5207
- */
5208
- stringify: function (command) {
5209
- keepUnused(command);
5210
- return "---"; // <- TODO: [🛋] Implement
5211
- },
5212
- /**
5213
- * Reads the FORMAT command from the `TemplateJson`
5214
- *
5215
- * Note: This is used in `pipelineJsonToString` utility
5216
- */
5217
- takeFromTemplateJson: function ($templateJson) {
5218
- keepUnused($templateJson);
5219
- throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
5220
- },
5221
- };
6054
+ finally { if (e_1) throw e_1.error; }
6055
+ }
6056
+ // TODO: [🐠] Following try-catch block should be part of common validators logic
6057
+ try {
6058
+ /*
6059
+ Note: We don't need to check for spaces because we are going to normalize the parameter name to camelCase
6060
+ if (parameterName.includes(' ')) {
6061
+ throw new ParseError(`Parameter name cannot contain spaces`);
6062
+ }
6063
+ */
6064
+ if (parameterName.includes('.')) {
6065
+ throw new ParseError("Parameter name cannot contain dots");
6066
+ }
6067
+ if (parameterName.includes('/') || parameterName.includes('\\')) {
6068
+ throw new ParseError("Parameter name cannot contain slashes");
6069
+ }
6070
+ if (parameterName.includes('(') ||
6071
+ parameterName.includes(')') ||
6072
+ parameterName.includes('{') ||
6073
+ parameterName.includes('}') ||
6074
+ parameterName.includes('[') ||
6075
+ parameterName.includes(']')) {
6076
+ throw new ParseError("Parameter name cannot contain braces");
6077
+ }
6078
+ parameterName = removeDiacritics(parameterName);
6079
+ parameterName = removeEmojis(parameterName);
6080
+ parameterName = removeQuotes(parameterName);
6081
+ parameterName = normalizeTo_camelCase(parameterName);
6082
+ if (parameterName === '') {
6083
+ throw new ParseError("Parameter name cannot be empty");
6084
+ }
6085
+ if (RESERVED_PARAMETER_NAMES.includes(parameterName)) {
6086
+ throw new ParseError("{".concat(parameterName, "} is a reserved parameter name"));
6087
+ }
6088
+ }
6089
+ catch (error) {
6090
+ if (!(error instanceof ParseError)) {
6091
+ throw error;
6092
+ }
6093
+ throw new ParseError(spaceTrim(function (block) { return "\n ".concat(block(error.message), "\n\n Tried to validate parameter name:\n ").concat(block(rawParameterName), "\n "); }));
6094
+ }
6095
+ return parameterName;
6096
+ }
5222
6097
 
5223
6098
  /**
5224
6099
  * Parses the foreach command
@@ -5249,25 +6124,61 @@ var foreachCommandParser = {
5249
6124
  /**
5250
6125
  * Link to discussion
5251
6126
  */
5252
- documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/@@',
6127
+ documentationUrl: 'https://github.com/webgptorg/promptbook/discussions/148',
5253
6128
  /**
5254
6129
  * Example usages of the FOREACH command
5255
6130
  */
5256
6131
  examples: [
5257
- 'FOREACH List Line -> `{customer}`',
5258
- 'FOR List Line -> `{customer}`',
5259
- 'EACH List Line -> `{customer}`',
5260
- // <- TODO: [🍭] More
6132
+ 'FOREACH Text Line `{customers}` -> `{customer}`',
6133
+ 'FOR Csv Row `{customers}` -> `{firstName}`, `{lastName}`',
6134
+ 'EACH Csv Cell `{customers}` -> `{subformat}`',
5261
6135
  ],
5262
6136
  /**
5263
6137
  * Parses the FOREACH command
5264
6138
  */
5265
6139
  parse: function (input) {
5266
6140
  var args = input.args;
5267
- keepUnused(args);
5268
- // <- TODO: [🍭] Implement
6141
+ var formatName = normalizeTo_SCREAMING_CASE(args[0] || '');
6142
+ var subformatName = normalizeTo_SCREAMING_CASE(args[1] || '');
6143
+ var parameterNameArg = args[2] || '';
6144
+ var assignSign = args[3];
6145
+ var formatDefinition = FORMAT_DEFINITIONS.find(function (formatDefinition) {
6146
+ return __spreadArray([formatDefinition.formatName], __read((formatDefinition.aliases || [])), false).includes(formatName);
6147
+ });
6148
+ if (formatDefinition === undefined) {
6149
+ throw new ParseError(spaceTrim(function (block) { return "\n Unsupported format \"".concat(formatName, "\"\n\n Available formats:\n ").concat(block(FORMAT_DEFINITIONS.map(function (formatDefinition) { return formatDefinition.formatName; })
6150
+ .map(function (formatName) { return "- ".concat(formatName); })
6151
+ .join('\n')), "\n "); }));
6152
+ // <- TODO: [🏢] List all supported format names
6153
+ }
6154
+ var subvalueDefinition = formatDefinition.subvalueDefinitions.find(function (subvalueDefinition) {
6155
+ return __spreadArray([subvalueDefinition.subvalueName], __read((subvalueDefinition.aliases || [])), false).includes(subformatName);
6156
+ });
6157
+ if (subvalueDefinition === undefined) {
6158
+ throw new ParseError(spaceTrim(function (block) { return "\n Unsupported subformat name \"".concat(subformatName, "\" for format \"").concat(formatName, "\"\n\n Available subformat names for format \"").concat(formatDefinition.formatName, "\":\n ").concat(block(formatDefinition.subvalueDefinitions
6159
+ .map(function (subvalueDefinition) { return subvalueDefinition.subvalueName; })
6160
+ .map(function (subvalueName) { return "- ".concat(subvalueName); })
6161
+ .join('\n')), "\n "); }));
6162
+ // <- TODO: [🏢] List all supported subformat names for the format
6163
+ }
6164
+ if (assignSign !== '->') {
6165
+ throw new ParseError("FOREACH command must have '->' to assign the value to the parameter");
6166
+ }
6167
+ var parameterName = validateParameterName(parameterNameArg);
6168
+ var subparameterNames = args
6169
+ .slice(4)
6170
+ .map(function (parameterName) { return parameterName.split(',').join(' ').trim(); })
6171
+ .filter(function (parameterName) { return parameterName !== ''; })
6172
+ .map(validateParameterName);
6173
+ if (subparameterNames.length === 0) {
6174
+ throw new ParseError("FOREACH command must have at least one subparameter");
6175
+ }
5269
6176
  return {
5270
6177
  type: 'FOREACH',
6178
+ formatName: formatName,
6179
+ subformatName: subformatName,
6180
+ parameterName: parameterName,
6181
+ subparameterNames: subparameterNames,
5271
6182
  };
5272
6183
  },
5273
6184
  /**
@@ -5276,8 +6187,12 @@ var foreachCommandParser = {
5276
6187
  * Note: `$` is used to indicate that this function mutates given `templateJson`
5277
6188
  */
5278
6189
  $applyToTemplateJson: function (command, $templateJson, $pipelineJson) {
5279
- keepUnused(command, $templateJson, $pipelineJson);
5280
- // <- TODO: [🍭] Implement
6190
+ var formatName = command.formatName, subformatName = command.subformatName, parameterName = command.parameterName, subparameterNames = command.subparameterNames;
6191
+ // TODO: [🍭] Detect double use
6192
+ // TODO: [🍭] Detect usage with JOKER and don't allow it
6193
+ $templateJson.foreach = { formatName: formatName, subformatName: subformatName, parameterName: parameterName, subparameterNames: subparameterNames };
6194
+ keepUnused($pipelineJson); // <- TODO: [🧠] Maybe register subparameter from foreach into parameters of the pipeline
6195
+ // Note: [🍭] FOREACH apply has some sideeffects on different places in codebase
5281
6196
  },
5282
6197
  /**
5283
6198
  * Converts the FOREACH command back to string
@@ -5286,8 +6201,7 @@ var foreachCommandParser = {
5286
6201
  */
5287
6202
  stringify: function (command) {
5288
6203
  keepUnused(command);
5289
- return "";
5290
- // <- TODO: [🍭] Implement
6204
+ return "---"; // <- TODO: [🛋] Implement
5291
6205
  },
5292
6206
  /**
5293
6207
  * Reads the FOREACH command from the `TemplateJson`
@@ -5296,12 +6210,11 @@ var foreachCommandParser = {
5296
6210
  */
5297
6211
  takeFromTemplateJson: function ($templateJson) {
5298
6212
  keepUnused($templateJson);
5299
- return [];
5300
- // <- TODO: [🍭] Implement
6213
+ throw new NotYetImplementedError("[\uD83D\uDECB] Not implemented yet"); // <- TODO: [🛋] Implement
5301
6214
  },
5302
6215
  };
5303
6216
  /**
5304
- * TODO: [🍭] Make .ptbk.md file with examples of the FOREACH command and also with wrong parsing and logic
6217
+ * TODO: [🍭] Make .ptbk.md file with examples of the FOREACH with wrong parsing and logic
5305
6218
  */
5306
6219
 
5307
6220
  /**
@@ -5411,11 +6324,11 @@ var jokerCommandParser = {
5411
6324
  */
5412
6325
  parse: function (input) {
5413
6326
  var args = input.args;
5414
- var parametersMatch = (args.pop() || '').match(/^\{(?<parameterName>[a-z0-9_]+)\}$/im);
5415
- if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
5416
- throw new ParseError("Invalid joker");
6327
+ if (args.length !== 1) {
6328
+ throw new ParseError("JOKE command expects exactly one parameter name");
5417
6329
  }
5418
- var parameterName = parametersMatch.groups.parameterName;
6330
+ var parameterNameArg = args[0] || '';
6331
+ var parameterName = validateParameterName(parameterNameArg);
5419
6332
  return {
5420
6333
  type: 'JOKER',
5421
6334
  parameterName: parameterName,
@@ -5490,6 +6403,9 @@ var modelCommandParser = {
5490
6403
  */
5491
6404
  parse: function (input) {
5492
6405
  var args = input.args, normalized = input.normalized;
6406
+ var availableVariantsMessage = spaceTrim(function (block) { return "\n Available variants are:\n ".concat(block(MODEL_VARIANTS.map(function (variantName) {
6407
+ return "- ".concat(variantName).concat(variantName !== 'EMBEDDING' ? '' : ' (Not available in pipeline)');
6408
+ }).join('\n')), "\n "); });
5493
6409
  // TODO: Make this more elegant and dynamically
5494
6410
  if (normalized.startsWith('MODEL_VARIANT')) {
5495
6411
  if (normalized === 'MODEL_VARIANT_CHAT') {
@@ -5505,17 +6421,13 @@ var modelCommandParser = {
5505
6421
  key: 'modelVariant',
5506
6422
  value: 'COMPLETION',
5507
6423
  };
6424
+ // <- Note: [🤖]
5508
6425
  }
5509
6426
  else if (normalized.startsWith('MODEL_VARIANT_EMBED')) {
5510
- return {
5511
- type: 'MODEL',
5512
- key: 'modelVariant',
5513
- value: 'EMBEDDING',
5514
- };
5515
- // <- Note: [🤖]
6427
+ spaceTrim(function (block) { return "\n Embedding model can not be used in pipeline\n\n ".concat(block(availableVariantsMessage), "\n "); });
5516
6428
  }
5517
6429
  else {
5518
- throw new ParseError(spaceTrim(function (block) { return "\n Unknown model variant in command:\n\n Supported variants are:\n ".concat(block(MODEL_VARIANTS.map(function (variantName) { return "- ".concat(variantName); }).join('\n')), "\n "); }));
6430
+ throw new ParseError(spaceTrim(function (block) { return "\n Unknown model variant in command:\n\n ".concat(block(availableVariantsMessage), "\n "); }));
5519
6431
  }
5520
6432
  }
5521
6433
  if (normalized.startsWith('MODEL_NAME')) {
@@ -5540,6 +6452,7 @@ var modelCommandParser = {
5540
6452
  if ($pipelineJson.defaultModelRequirements[command.key] !== undefined) {
5541
6453
  if ($pipelineJson.defaultModelRequirements[command.key] === command.value) {
5542
6454
  console.warn("Multiple commands `MODEL ".concat(command.key, " ").concat(command.value, "` in the pipeline head"));
6455
+ // <- TODO: [🚎] Some better way how to get warnings from pipeline parsing / logic
5543
6456
  }
5544
6457
  else {
5545
6458
  throw new ParseError(spaceTrim("\n Redefinition of MODEL `".concat(command.key, "` in the pipeline head\n\n You have used:\n - MODEL ").concat(command.key, " ").concat($pipelineJson.defaultModelRequirements[command.key], "\n - MODEL ").concat(command.key, " ").concat(command.value, "\n ")));
@@ -5639,14 +6552,13 @@ var parameterCommandParser = {
5639
6552
  * Parses the PARAMETER command
5640
6553
  */
5641
6554
  parse: function (input) {
5642
- var normalized = input.normalized, raw = input.raw;
5643
- var parametersMatch = raw.match(/\{(?<parameterName>[a-z0-9_]+)\}[^\S\r\n]*(?<parameterDescription>.*)$/im);
5644
- if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
5645
- throw new ParseError("Invalid parameter");
5646
- }
5647
- var _a = parametersMatch.groups, parameterName = _a.parameterName, parameterDescription = _a.parameterDescription;
5648
- if (parameterDescription && parameterDescription.match(/\{(?<parameterName>[a-z0-9_]+)\}/im)) {
5649
- throw new ParseError("Parameter {".concat(parameterName, "} can not contain another parameter in description"));
6555
+ var normalized = input.normalized, args = input.args, raw = input.raw;
6556
+ var parameterNameRaw = args.shift() || '';
6557
+ var parameterDescriptionRaw = args.join(' ');
6558
+ // <- TODO: When [🥶] fixed, change to:
6559
+ // > const parameterDescriptionRaw = rawArgs.split(parameterNameRaw).join('').trim();
6560
+ if (parameterDescriptionRaw && parameterDescriptionRaw.match(/\{(?<embeddedParameterName>[a-z0-9_]+)\}/im)) {
6561
+ throw new ParseError(spaceTrim(function (block) { return "\n Parameter {".concat(parameterNameRaw, "} can not contain another parameter in description\n\n The description:\n ").concat(block(parameterDescriptionRaw), "\n "); }));
5650
6562
  }
5651
6563
  var isInput = normalized.startsWith('INPUT');
5652
6564
  var isOutput = normalized.startsWith('OUTPUT');
@@ -5654,10 +6566,12 @@ var parameterCommandParser = {
5654
6566
  isInput = false;
5655
6567
  isOutput = false;
5656
6568
  }
6569
+ var parameterName = validateParameterName(parameterNameRaw);
6570
+ var parameterDescription = parameterDescriptionRaw.trim() || null;
5657
6571
  return {
5658
6572
  type: 'PARAMETER',
5659
6573
  parameterName: parameterName,
5660
- parameterDescription: parameterDescription.trim() || null,
6574
+ parameterDescription: parameterDescription,
5661
6575
  isInput: isInput,
5662
6576
  isOutput: isOutput,
5663
6577
  };
@@ -6407,76 +7321,6 @@ function removeMarkdownFormatting(str) {
6407
7321
  return str;
6408
7322
  }
6409
7323
 
6410
- /**
6411
- * @@@
6412
- *
6413
- * @param text @@@
6414
- * @returns @@@
6415
- * @example 'HELLO_WORLD'
6416
- * @example 'I_LOVE_PROMPTBOOK'
6417
- * @public exported from `@promptbook/utils`
6418
- */
6419
- function normalizeTo_SCREAMING_CASE(text) {
6420
- var e_1, _a;
6421
- var charType;
6422
- var lastCharType = 'OTHER';
6423
- var normalizedName = '';
6424
- try {
6425
- for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
6426
- var char = text_1_1.value;
6427
- var normalizedChar = void 0;
6428
- if (/^[a-z]$/.test(char)) {
6429
- charType = 'LOWERCASE';
6430
- normalizedChar = char.toUpperCase();
6431
- }
6432
- else if (/^[A-Z]$/.test(char)) {
6433
- charType = 'UPPERCASE';
6434
- normalizedChar = char;
6435
- }
6436
- else if (/^[0-9]$/.test(char)) {
6437
- charType = 'NUMBER';
6438
- normalizedChar = char;
6439
- }
6440
- else if (/^\/$/.test(char)) {
6441
- charType = 'SLASH';
6442
- normalizedChar = char;
6443
- }
6444
- else {
6445
- charType = 'OTHER';
6446
- normalizedChar = '_';
6447
- }
6448
- if (charType !== lastCharType &&
6449
- !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
6450
- !(lastCharType === 'NUMBER') &&
6451
- !(charType === 'NUMBER')) {
6452
- normalizedName += '_';
6453
- }
6454
- normalizedName += normalizedChar;
6455
- lastCharType = charType;
6456
- }
6457
- }
6458
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
6459
- finally {
6460
- try {
6461
- if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
6462
- }
6463
- finally { if (e_1) throw e_1.error; }
6464
- }
6465
- normalizedName = normalizedName.replace(/_+/g, '_');
6466
- normalizedName = normalizedName.replace(/_?\/_?/g, '/');
6467
- normalizedName = normalizedName.replace(/^_/, '');
6468
- normalizedName = normalizedName.replace(/_$/, '');
6469
- return normalizedName;
6470
- }
6471
- /**
6472
- * TODO: Tests
6473
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'Moje tabule' })).toEqual('/VtG7sR9rRJqwNEdM2/Moje tabule');
6474
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'ěščřžžýáíúů' })).toEqual('/VtG7sR9rRJqwNEdM2/escrzyaieuu');
6475
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj');
6476
- * > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: ' ahoj_ahojAhoj ahoj ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj-ahoj-ahoj-ahoj');
6477
- * TODO: [🌺] Use some intermediate util splitWords
6478
- */
6479
-
6480
7324
  /**
6481
7325
  * Parses one line of ul/ol to command
6482
7326
  *
@@ -6489,6 +7333,7 @@ function parseCommand(raw, usagePlace) {
6489
7333
  if (raw.includes('\n') || raw.includes('\r')) {
6490
7334
  throw new ParseError('Command can not contain new line characters' /* <- TODO: [🚞] */);
6491
7335
  }
7336
+ // TODO: Unit test all this processing and parsing
6492
7337
  var normalized = raw.trim();
6493
7338
  normalized = normalized.split('`').join('');
6494
7339
  normalized = normalized.split('"').join('');
@@ -6534,7 +7379,9 @@ function parseCommand(raw, usagePlace) {
6534
7379
  for (var commandNameSegmentsCount = 0; commandNameSegmentsCount < Math.min(items.length, 3); commandNameSegmentsCount++) {
6535
7380
  var commandNameRaw = items.slice(0, commandNameSegmentsCount + 1).join('_');
6536
7381
  var args = items.slice(commandNameSegmentsCount + 1);
6537
- var rawArgs = raw.substring(commandNameRaw.length).trim();
7382
+ var rawArgs = raw
7383
+ .substring(commandNameRaw.length)
7384
+ .trim();
6538
7385
  var command = parseCommandVariant({ usagePlace: usagePlace, raw: raw, rawArgs: rawArgs, normalized: normalized, args: args, commandNameRaw: commandNameRaw });
6539
7386
  if (command !== null) {
6540
7387
  return command;
@@ -6544,8 +7391,10 @@ function parseCommand(raw, usagePlace) {
6544
7391
  // Arg1 Arg2 Arg3 | FOO
6545
7392
  {
6546
7393
  var commandNameRaw = items.slice(-1).join('_');
6547
- var args = items.slice(0, -1);
6548
- var rawArgs = raw.substring(0, raw.length - commandNameRaw.length).trim();
7394
+ var args = items.slice(0, -1); // <- Note: This is probbably not correct
7395
+ var rawArgs = raw
7396
+ .substring(0, raw.length - commandNameRaw.length)
7397
+ .trim();
6549
7398
  var command = parseCommandVariant({ usagePlace: usagePlace, raw: raw, rawArgs: rawArgs, normalized: normalized, args: args, commandNameRaw: commandNameRaw });
6550
7399
  if (command !== null) {
6551
7400
  return command;
@@ -6685,7 +7534,7 @@ function extractAllListItemsFromMarkdown(markdown) {
6685
7534
  function extractOneBlockFromMarkdown(markdown) {
6686
7535
  var codeBlocks = extractAllBlocksFromMarkdown(markdown);
6687
7536
  if (codeBlocks.length !== 1) {
6688
- throw new ParseError(spaceTrim(function (block) { return "\n There should be exactly 1 code block, found ".concat(codeBlocks.length, " code blocks\n\n ").concat(block(codeBlocks.map(function (block, i) { return "Block ".concat(i + 1, ":\n").concat(block.content); }).join('\n\n\n')), "\n "); }));
7537
+ throw new ParseError(spaceTrim(function (block) { return "\n There should be exactly 1 code block in template, found ".concat(codeBlocks.length, " code blocks\n\n ").concat(block(codeBlocks.map(function (block, i) { return "Block ".concat(i + 1, ":\n").concat(block.content); }).join('\n\n\n')), "\n "); }));
6689
7538
  }
6690
7539
  return codeBlocks[0];
6691
7540
  }
@@ -7244,70 +8093,6 @@ function addAutoGeneratedSection(content, options) {
7244
8093
  * TODO: [🏛] This can be part of markdown builder
7245
8094
  */
7246
8095
 
7247
- /**
7248
- * @@@
7249
- *
7250
- * @param text @@@
7251
- * @param _isFirstLetterCapital @@@
7252
- * @returns @@@
7253
- * @example 'helloWorld'
7254
- * @example 'iLovePromptbook'
7255
- * @public exported from `@promptbook/utils`
7256
- */
7257
- function normalizeTo_camelCase(text, _isFirstLetterCapital) {
7258
- var e_1, _a;
7259
- if (_isFirstLetterCapital === void 0) { _isFirstLetterCapital = false; }
7260
- var charType;
7261
- var lastCharType = null;
7262
- var normalizedName = '';
7263
- try {
7264
- for (var text_1 = __values(text), text_1_1 = text_1.next(); !text_1_1.done; text_1_1 = text_1.next()) {
7265
- var char = text_1_1.value;
7266
- var normalizedChar = void 0;
7267
- if (/^[a-z]$/.test(char)) {
7268
- charType = 'LOWERCASE';
7269
- normalizedChar = char;
7270
- }
7271
- else if (/^[A-Z]$/.test(char)) {
7272
- charType = 'UPPERCASE';
7273
- normalizedChar = char.toLowerCase();
7274
- }
7275
- else if (/^[0-9]$/.test(char)) {
7276
- charType = 'NUMBER';
7277
- normalizedChar = char;
7278
- }
7279
- else {
7280
- charType = 'OTHER';
7281
- normalizedChar = '';
7282
- }
7283
- if (!lastCharType) {
7284
- if (_isFirstLetterCapital) {
7285
- normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
7286
- }
7287
- }
7288
- else if (charType !== lastCharType &&
7289
- !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
7290
- !(lastCharType === 'NUMBER') &&
7291
- !(charType === 'NUMBER')) {
7292
- normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
7293
- }
7294
- normalizedName += normalizedChar;
7295
- lastCharType = charType;
7296
- }
7297
- }
7298
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
7299
- finally {
7300
- try {
7301
- if (text_1_1 && !text_1_1.done && (_a = text_1.return)) _a.call(text_1);
7302
- }
7303
- finally { if (e_1) throw e_1.error; }
7304
- }
7305
- return normalizedName;
7306
- }
7307
- /**
7308
- * TODO: [🌺] Use some intermediate util splitWords
7309
- */
7310
-
7311
8096
  /**
7312
8097
  * Creates a Mermaid graph based on the promptbook
7313
8098
  *
@@ -7364,6 +8149,9 @@ function renderPromptbookMermaid(pipelineJson, options) {
7364
8149
  return promptbookMermaid;
7365
8150
  }
7366
8151
  /**
8152
+ * TODO: !!!!! FOREACH in mermaid graph
8153
+ * TODO: !!!!! Knowledge in mermaid graph
8154
+ * TODO: !!!!! Personas in mermaid graph
7367
8155
  * TODO: Maybe use some Mermaid package instead of string templating
7368
8156
  * TODO: [🕌] When more than 2 functionalities, split into separate functions
7369
8157
  */
@@ -7505,21 +8293,41 @@ function usageToWorktime(usage) {
7505
8293
  * @public exported from `@promptbook/core`
7506
8294
  */
7507
8295
  function usageToHuman(usage) {
7508
- var report = 'Usage:';
8296
+ var reportItems = [];
7509
8297
  var uncertainNumberToHuman = function (_a) {
7510
8298
  var value = _a.value, isUncertain = _a.isUncertain;
7511
8299
  return "".concat(isUncertain ? 'approximately ' : '').concat(Math.round(value * 100) / 100);
7512
8300
  };
7513
- report += '\n' + "- Cost ".concat(uncertainNumberToHuman(usage.price), " USD");
7514
- report += '\n' + "- Saved ".concat(uncertainNumberToHuman(usageToWorktime(usage)), " hours of human time");
7515
- return spaceTrim(report);
8301
+ if (usage.price.value > 0.01
8302
+ // <- TODO: [🍓][🧞‍♂️][👩🏽‍🤝‍🧑🏻] Configure negligible value - default value to config + value to `UsageToHumanSettings`
8303
+ ) {
8304
+ reportItems.push("Cost ".concat(uncertainNumberToHuman(usage.price), " USD"));
8305
+ }
8306
+ else {
8307
+ reportItems.push("Negligible cost");
8308
+ }
8309
+ var worktime = usageToWorktime(usage);
8310
+ if (worktime.value >
8311
+ 1 / 60
8312
+ // <- TODO: [🍓][🧞‍♂️][👩🏽‍🤝‍🧑🏻]
8313
+ ) {
8314
+ reportItems.push("Saved ".concat(uncertainNumberToHuman(usageToWorktime(usage)), " hours of human time"));
8315
+ // TODO: [🍓][🧞‍♂️] Show minutes, seconds, days NOT 0.1 hours
8316
+ }
8317
+ if (usage.output.charactersCount.value > 0) {
8318
+ reportItems.push("Written ".concat(uncertainNumberToHuman(usage.output.charactersCount), " characters"));
8319
+ }
8320
+ if (reportItems.length === 0) {
8321
+ // Note: For negligible usage, we report at least something
8322
+ reportItems.push('Negligible');
8323
+ }
8324
+ return spaceTrim(function (block) { return "\n Usage:\n ".concat(block(reportItems.map(function (item) { return "- ".concat(item); }).join('\n')), "\n "); });
7516
8325
  }
7517
8326
  /**
7518
- * TODO: Use "$1" not "1 USD"
7519
- * TODO: Use markdown formatting like "Cost approximately **$1**"
7520
- * TODO: Report in minutes, seconds, days NOT 0.1 hours
8327
+ * TODO: [🍓][🧞‍♂️] Use "$1" not "1 USD"
8328
+ * TODO: [🍓][🧞‍♂️] Use markdown formatting like "Cost approximately **$1**"
8329
+ * TODO: [🍓][🧞‍♂️] Report in minutes, seconds, days NOT 0.1 hours
7521
8330
  * TODO: [🧠] Maybe make from `uncertainNumberToHuman` separate exported utility
7522
- * TODO: When negligible usage, report "Negligible" or just don't report it
7523
8331
  * TODO: [🧠] Maybe use "~" instead of "approximately"
7524
8332
  * TODO: [🏛] Maybe make some markdown builder
7525
8333
  */
@@ -8107,6 +8915,42 @@ var _OpenAiMetadataRegistration = $llmToolsMetadataRegister.register({
8107
8915
  return null;
8108
8916
  },
8109
8917
  });
8918
+ /**
8919
+ * @@@ registration1 of default configuration for Open AI
8920
+ *
8921
+ * Note: [🏐] Configurations registrations are done in @@@ BUT constructor @@@
8922
+ *
8923
+ * @public exported from `@promptbook/core`
8924
+ * @public exported from `@promptbook/cli`
8925
+ */
8926
+ var _OpenAiAssistantMetadataRegistration = $llmToolsMetadataRegister.register({
8927
+ title: 'Open AI Assistant',
8928
+ packageName: '@promptbook/openai',
8929
+ className: 'OpenAiAssistantExecutionTools',
8930
+ getBoilerplateConfiguration: function () {
8931
+ return {
8932
+ title: 'Open AI Assistant (boilerplate)',
8933
+ packageName: '@promptbook/openai',
8934
+ className: 'OpenAiAssistantExecutionTools',
8935
+ options: {
8936
+ apiKey: 'sk-',
8937
+ },
8938
+ };
8939
+ },
8940
+ createConfigurationFromEnv: function (env) {
8941
+ if (typeof env.OPENAI_API_KEY === 'string') {
8942
+ return {
8943
+ title: 'Open AI Assistant (from env)',
8944
+ packageName: '@promptbook/openai',
8945
+ className: 'OpenAiAssistantExecutionTools',
8946
+ options: {
8947
+ apiKey: process.env.OPENAI_API_KEY,
8948
+ },
8949
+ };
8950
+ }
8951
+ return null;
8952
+ },
8953
+ });
8110
8954
 
8111
8955
  /**
8112
8956
  * This class behaves like LocalStorage but separates keys by prefix
@@ -8168,8 +9012,8 @@ function formatNumber(value) {
8168
9012
  */
8169
9013
  function createMarkdownTable(table) {
8170
9014
  var columnWidths = table.reduce(function (widths, row) {
8171
- row.forEach(function (cell, columnIndex) {
8172
- var cellLength = cell.length;
9015
+ row.forEach(function (subformat, columnIndex) {
9016
+ var cellLength = subformat.length;
8173
9017
  if (!widths[columnIndex] || cellLength > widths[columnIndex]) {
8174
9018
  widths[columnIndex] = cellLength;
8175
9019
  }
@@ -8177,12 +9021,12 @@ function createMarkdownTable(table) {
8177
9021
  return widths;
8178
9022
  }, []);
8179
9023
  var header = "| ".concat(table[0]
8180
- .map(function (cell, columnIndex) { return cell.padEnd(columnWidths[columnIndex]); })
9024
+ .map(function (subformat, columnIndex) { return subformat.padEnd(columnWidths[columnIndex]); })
8181
9025
  .join(' | '), " |");
8182
9026
  var separator = "|".concat(columnWidths.map(function (width) { return '-'.repeat(width + 2); }).join('|'), "|");
8183
9027
  var rows = table.slice(1).map(function (row) {
8184
- var paddedRow = row.map(function (cell, columnIndex) {
8185
- return cell.padEnd(columnWidths[columnIndex]);
9028
+ var paddedRow = row.map(function (subformat, columnIndex) {
9029
+ return subformat.padEnd(columnWidths[columnIndex]);
8186
9030
  });
8187
9031
  return "| ".concat(paddedRow.join(' | '), " |");
8188
9032
  });
@@ -8458,5 +9302,5 @@ function executionReportJsonToString(executionReportJson, options) {
8458
9302
  * TODO: [🧠] Should be in generated file GENERATOR_WARNING
8459
9303
  */
8460
9304
 
8461
- export { $llmToolsMetadataRegister, $llmToolsRegister, CLAIM, CallbackInterfaceTools, CollectionError, DEFAULT_REMOTE_URL, DEFAULT_REMOTE_URL_PATH, ERRORS, EXECUTIONS_CACHE_DIRNAME, EXPECTATION_UNITS, EnvironmentMismatchError, ExecutionReportStringOptionsDefaults, ExpectError, IS_VERBOSE, LimitReachedError, MAX_EXECUTION_ATTEMPTS, MAX_FILENAME_LENGTH, MAX_KNOWLEDGE_SOURCES_SCRAPING_DEPTH, MAX_KNOWLEDGE_SOURCES_SCRAPING_TOTAL, MAX_PARALLEL_COUNT, MODEL_VARIANTS, MemoryStorage, NotFoundError, NotYetImplementedError, PIPELINE_COLLECTION_BASE_FILENAME, PROMPTBOOK_VERSION, ParseError, PipelineExecutionError, PipelineLogicError, PipelineUrlError, PrefixStorage, RESERVED_PARAMETER_NAMES, TemplateTypes, UNCERTAIN_USAGE, UnexpectedError, ZERO_USAGE, _AnthropicClaudeMetadataRegistration, _AzureOpenAiMetadataRegistration, _OpenAiMetadataRegistration, addUsage, assertsExecutionSuccessful, cacheLlmTools, collectionToJson, countTotalUsage, createCollectionFromJson, createCollectionFromPromise, createCollectionFromUrl, createLlmToolsFromConfiguration, createPipelineExecutor, createSubcollection, embeddingVectorToString, executionReportJsonToString, isPassingExpectations, isPipelinePrepared, joinLlmExecutionTools, limitTotalUsage, pipelineJsonToString, pipelineStringToJson, pipelineStringToJsonSync, prepareKnowledgeFromMarkdown, prepareKnowledgePieces, preparePersona, preparePipeline, prepareTemplates, prettifyPipelineString, stringifyPipelineJson, unpreparePipeline, usageToHuman, usageToWorktime, validatePipeline };
9305
+ export { $llmToolsMetadataRegister, $llmToolsRegister, CLAIM, CallbackInterfaceTools, CollectionError, CsvFormatDefinition, DEFAULT_CSV_SETTINGS, DEFAULT_REMOTE_URL, DEFAULT_REMOTE_URL_PATH, ERRORS, EXECUTIONS_CACHE_DIRNAME, EXPECTATION_UNITS, EnvironmentMismatchError, ExecutionReportStringOptionsDefaults, ExpectError, IS_VERBOSE, 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, NotFoundError, NotYetImplementedError, PIPELINE_COLLECTION_BASE_FILENAME, PROMPTBOOK_VERSION, ParseError, PipelineExecutionError, PipelineLogicError, PipelineUrlError, PrefixStorage, RESERVED_PARAMETER_NAMES, TemplateTypes, TextFormatDefinition, UNCERTAIN_USAGE, UnexpectedError, ZERO_USAGE, _AnthropicClaudeMetadataRegistration, _AzureOpenAiMetadataRegistration, _OpenAiAssistantMetadataRegistration, _OpenAiMetadataRegistration, addUsage, assertsExecutionSuccessful, cacheLlmTools, collectionToJson, countTotalUsage, createCollectionFromJson, createCollectionFromPromise, createCollectionFromUrl, createLlmToolsFromConfiguration, createPipelineExecutor, createSubcollection, embeddingVectorToString, executionReportJsonToString, isPassingExpectations, isPipelinePrepared, joinLlmExecutionTools, limitTotalUsage, pipelineJsonToString, pipelineStringToJson, pipelineStringToJsonSync, prepareKnowledgeFromMarkdown, prepareKnowledgePieces, preparePersona, preparePipeline, prepareTemplates, prettifyPipelineString, stringifyPipelineJson, unpreparePipeline, usageToHuman, usageToWorktime, validatePipeline };
8462
9306
  //# sourceMappingURL=index.es.js.map