@promptbook/core 0.29.0 → 0.30.0-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/esm/index.es.js +506 -505
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/_packages/core.index.d.ts +1 -2
  4. package/esm/typings/classes/PromptTemplatePipelineLibrary.d.ts +2 -3
  5. package/esm/typings/conversion/validatePromptTemplatePipelineJson.d.ts +1 -1
  6. package/esm/typings/execution/createPtpExecutor.d.ts +2 -2
  7. package/esm/typings/types/PromptTemplatePipelineJson/PromptTemplateJson.d.ts +7 -1
  8. package/esm/typings/types/PromptTemplatePipelineJson/PromptTemplatePipelineJson.d.ts +0 -1
  9. package/esm/typings/types/PromptTemplatePipelineString.d.ts +0 -1
  10. package/esm/typings/utils/extractParameters.d.ts +8 -0
  11. package/esm/typings/utils/extractParameters.test.d.ts +1 -0
  12. package/package.json +1 -1
  13. package/umd/index.umd.js +505 -505
  14. package/umd/index.umd.js.map +1 -1
  15. package/umd/typings/_packages/core.index.d.ts +1 -2
  16. package/umd/typings/classes/PromptTemplatePipelineLibrary.d.ts +2 -3
  17. package/umd/typings/conversion/validatePromptTemplatePipelineJson.d.ts +1 -1
  18. package/umd/typings/execution/createPtpExecutor.d.ts +2 -2
  19. package/umd/typings/types/PromptTemplatePipelineJson/PromptTemplateJson.d.ts +7 -1
  20. package/umd/typings/types/PromptTemplatePipelineJson/PromptTemplatePipelineJson.d.ts +0 -1
  21. package/umd/typings/types/PromptTemplatePipelineString.d.ts +0 -1
  22. package/umd/typings/utils/extractParameters.d.ts +8 -0
  23. package/umd/typings/utils/extractParameters.test.d.ts +1 -0
  24. package/esm/typings/classes/PromptTemplatePipeline.d.ts +0 -71
  25. package/umd/typings/classes/PromptTemplatePipeline.d.ts +0 -71
package/umd/index.umd.js CHANGED
@@ -115,6 +115,16 @@
115
115
  finally { if (e) throw e.error; }
116
116
  }
117
117
  return ar;
118
+ }
119
+
120
+ function __spreadArray(to, from, pack) {
121
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
122
+ if (ar || !(i in from)) {
123
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
124
+ ar[i] = from[i];
125
+ }
126
+ }
127
+ return to.concat(ar || Array.prototype.slice.call(from));
118
128
  }
119
129
 
120
130
  /**
@@ -141,6 +151,35 @@
141
151
  */
142
152
  var SUPPORTED_SCRIPT_LANGUAGES = ['javascript', 'typescript', 'python'];
143
153
 
154
+ /**
155
+ * Parses the template and returns the list of all parameter names
156
+ *
157
+ * @param template the template with parameters in {curly} braces
158
+ * @returns the list of parameter names
159
+ */
160
+ function extractParameters(template) {
161
+ var e_1, _a;
162
+ var matches = template.matchAll(/{\w+}/g);
163
+ var parameterNames = [];
164
+ try {
165
+ for (var matches_1 = __values(matches), matches_1_1 = matches_1.next(); !matches_1_1.done; matches_1_1 = matches_1.next()) {
166
+ var match = matches_1_1.value;
167
+ var parameterName = match[0].slice(1, -1);
168
+ if (!parameterNames.includes(parameterName)) {
169
+ parameterNames.push(parameterName);
170
+ }
171
+ }
172
+ }
173
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
174
+ finally {
175
+ try {
176
+ if (matches_1_1 && !matches_1_1.done && (_a = matches_1.return)) _a.call(matches_1);
177
+ }
178
+ finally { if (e_1) throw e_1.error; }
179
+ }
180
+ return parameterNames;
181
+ }
182
+
144
183
  /**
145
184
  * Computes the deepness of the markdown structure.
146
185
  *
@@ -775,10 +814,11 @@
775
814
  finally { if (e_1) throw e_1.error; }
776
815
  }
777
816
  var _loop_1 = function (section) {
778
- var e_3, _e;
817
+ var e_3, _e, e_4, _f;
779
818
  // TODO: Parse prompt template description (the content out of the codeblock and lists)
780
819
  var templateModelRequirements = __assign({}, defaultModelRequirements);
781
820
  var listItems_3 = extractAllListItemsFromMarkdown(section.content);
821
+ var dependentParameterNames = [];
782
822
  var executionType = 'PROMPT_TEMPLATE';
783
823
  var jokers = [];
784
824
  var postprocessing = [];
@@ -792,6 +832,7 @@
792
832
  switch (command.type) {
793
833
  case 'JOKER':
794
834
  jokers.push(command.parameterName);
835
+ dependentParameterNames.push(command.parameterName);
795
836
  break;
796
837
  case 'EXECUTE':
797
838
  if (isExecutionTypeChanged) {
@@ -805,6 +846,7 @@
805
846
  templateModelRequirements[command.key] = command.value;
806
847
  break;
807
848
  case 'PARAMETER':
849
+ // Note: This is just for detecting resulitng parameter name
808
850
  addParam(command);
809
851
  break;
810
852
  case 'POSTPROCESS':
@@ -845,7 +887,7 @@
845
887
  }
846
888
  finally { if (e_3) throw e_3.error; }
847
889
  }
848
- var _f = extractOneBlockFromMarkdown(section.content), language = _f.language, content = _f.content;
890
+ var _g = extractOneBlockFromMarkdown(section.content), language = _g.language, content = _g.content;
849
891
  if (executionType === 'SCRIPT') {
850
892
  if (!language) {
851
893
  throw new Error('You must specify the language of the script in the prompt template');
@@ -884,10 +926,24 @@
884
926
  if (Object.keys(postprocessing).length === 0) {
885
927
  postprocessing = undefined;
886
928
  }
929
+ try {
930
+ for (var _h = (e_4 = void 0, __values(__spreadArray(__spreadArray(__spreadArray([], __read(extractParameters(section.title)), false), __read(extractParameters(description_1 || '')), false), __read(extractParameters(content)), false))), _j = _h.next(); !_j.done; _j = _h.next()) {
931
+ var parameterName = _j.value;
932
+ dependentParameterNames.push(parameterName);
933
+ }
934
+ }
935
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
936
+ finally {
937
+ try {
938
+ if (_j && !_j.done && (_f = _h.return)) _f.call(_h);
939
+ }
940
+ finally { if (e_4) throw e_4.error; }
941
+ }
887
942
  ptbJson.promptTemplates.push({
888
943
  name: n12.normalizeTo_PascalCase(section.title),
889
944
  title: section.title,
890
945
  description: description_1,
946
+ dependentParameterNames: dependentParameterNames,
891
947
  executionType: executionType,
892
948
  jokers: jokers,
893
949
  postprocessing: postprocessing,
@@ -935,7 +991,7 @@
935
991
  * @throws {Error} if invalid
936
992
  */
937
993
  function validatePromptTemplatePipelineJson(ptp) {
938
- var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
994
+ var e_1, _a, e_2, _b, e_3, _c;
939
995
  var definedParameters = new Set(ptp.parameters.filter(function (_a) {
940
996
  var isInput = _a.isInput;
941
997
  return isInput;
@@ -944,52 +1000,37 @@
944
1000
  return name;
945
1001
  }));
946
1002
  try {
947
- for (var _e = __values(ptp.promptTemplates), _f = _e.next(); !_f.done; _f = _e.next()) {
948
- var template = _f.value;
949
- try {
950
- for (var _g = (e_2 = void 0, __values(Array.from(template.content.matchAll(/\{(?<parameterName>[a-z0-9_]+)\}/gi)))), _h = _g.next(); !_h.done; _h = _g.next()) {
951
- var match = _h.value;
952
- var parameterName = match.groups.parameterName;
953
- if (!definedParameters.has(parameterName)) {
954
- throw new Error("Parameter {".concat(parameterName, "} used before defined"));
955
- }
956
- }
957
- }
958
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
959
- finally {
960
- try {
961
- if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
962
- }
963
- finally { if (e_2) throw e_2.error; }
964
- }
1003
+ // Note: Check each template individually
1004
+ for (var _d = __values(ptp.promptTemplates), _e = _d.next(); !_e.done; _e = _d.next()) {
1005
+ var template = _e.value;
965
1006
  if (definedParameters.has(template.resultingParameterName)) {
966
1007
  throw new Error("Parameter {".concat(template.resultingParameterName, "} is defined multiple times"));
967
1008
  }
968
1009
  if (template.jokers && template.jokers.length > 0) {
1010
+ if (!template.expectFormat &&
1011
+ !template.expectAmount /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
1012
+ throw new Error("Joker parameters are used but no expectations are defined");
1013
+ }
969
1014
  try {
970
- for (var _j = (e_3 = void 0, __values(template.jokers)), _k = _j.next(); !_k.done; _k = _j.next()) {
971
- var joker = _k.value;
972
- if (!definedParameters.has(joker)) {
973
- throw new Error("Joker parameter {".concat(joker, "} used before defined"));
1015
+ for (var _f = (e_2 = void 0, __values(template.jokers)), _g = _f.next(); !_g.done; _g = _f.next()) {
1016
+ var joker = _g.value;
1017
+ if (!template.dependentParameterNames.includes(joker)) {
1018
+ throw new Error("Parameter {".concat(joker, "} is used as joker but not in dependentParameterNames"));
974
1019
  }
975
1020
  }
976
1021
  }
977
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
1022
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
978
1023
  finally {
979
1024
  try {
980
- if (_k && !_k.done && (_c = _j.return)) _c.call(_j);
1025
+ if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
981
1026
  }
982
- finally { if (e_3) throw e_3.error; }
983
- }
984
- if (!template.expectFormat &&
985
- !template.expectAmount /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
986
- throw new Error("Joker parameters are used but no expectations are defined");
1027
+ finally { if (e_2) throw e_2.error; }
987
1028
  }
988
1029
  }
989
1030
  if (template.expectAmount) {
990
1031
  try {
991
- for (var _l = (e_4 = void 0, __values(Object.entries(template.expectAmount))), _m = _l.next(); !_m.done; _m = _l.next()) {
992
- var _o = __read(_m.value, 2), unit = _o[0], _p = _o[1], min = _p.min, max = _p.max;
1032
+ for (var _h = (e_3 = void 0, __values(Object.entries(template.expectAmount))), _j = _h.next(); !_j.done; _j = _h.next()) {
1033
+ var _k = __read(_j.value, 2), unit = _k[0], _l = _k[1], min = _l.min, max = _l.max;
993
1034
  if (min !== undefined && max !== undefined && min > max) {
994
1035
  throw new Error("Min expectation (=".concat(min, ") of ").concat(unit, " is higher than max expectation (=").concat(max, ")"));
995
1036
  }
@@ -1001,12 +1042,12 @@
1001
1042
  }
1002
1043
  }
1003
1044
  }
1004
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
1045
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
1005
1046
  finally {
1006
1047
  try {
1007
- if (_m && !_m.done && (_d = _l.return)) _d.call(_l);
1048
+ if (_j && !_j.done && (_c = _h.return)) _c.call(_h);
1008
1049
  }
1009
- finally { if (e_4) throw e_4.error; }
1050
+ finally { if (e_3) throw e_3.error; }
1010
1051
  }
1011
1052
  }
1012
1053
  definedParameters.add(template.resultingParameterName);
@@ -1015,10 +1056,42 @@
1015
1056
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
1016
1057
  finally {
1017
1058
  try {
1018
- if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
1059
+ if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
1019
1060
  }
1020
1061
  finally { if (e_1) throw e_1.error; }
1021
1062
  }
1063
+ // Note: Detect circular dependencies
1064
+ var resovedParameters = ptp.parameters.filter(function (_a) {
1065
+ var isInput = _a.isInput;
1066
+ return isInput;
1067
+ }).map(function (_a) {
1068
+ var name = _a.name;
1069
+ return name;
1070
+ });
1071
+ var unresovedTemplates = __spreadArray([], __read(ptp.promptTemplates), false);
1072
+ var _loop_1 = function () {
1073
+ var currentlyResovedTemplates = unresovedTemplates.filter(function (template) {
1074
+ return template.dependentParameterNames.every(function (name) { return resovedParameters.includes(name); });
1075
+ });
1076
+ if (currentlyResovedTemplates.length === 0) {
1077
+ throw new Error(spaceTrim__default["default"](function (block) { return "\n\n Can not resolve some parameters\n It may be circular dependencies\n\n Can not resolve:\n ".concat(block(unresovedTemplates
1078
+ .map(function (_a) {
1079
+ var resultingParameterName = _a.resultingParameterName, dependentParameterNames = _a.dependentParameterNames;
1080
+ return "- {".concat(resultingParameterName, "} depends on ").concat(dependentParameterNames
1081
+ .map(function (dependentParameterName) { return "{".concat(dependentParameterName, "}"); })
1082
+ .join(', '));
1083
+ })
1084
+ .join('\n')), "\n\n Resolved:\n ").concat(block(resovedParameters.map(function (name) { return "- {".concat(name, "}"); }).join('\n')), "\n "); }));
1085
+ }
1086
+ resovedParameters = __spreadArray(__spreadArray([], __read(resovedParameters), false), __read(currentlyResovedTemplates.map(function (_a) {
1087
+ var resultingParameterName = _a.resultingParameterName;
1088
+ return resultingParameterName;
1089
+ })), false);
1090
+ unresovedTemplates = unresovedTemplates.filter(function (template) { return !currentlyResovedTemplates.includes(template); });
1091
+ };
1092
+ while (unresovedTemplates.length > 0) {
1093
+ _loop_1();
1094
+ }
1022
1095
  }
1023
1096
  /**
1024
1097
  * TODO: [🧠] Work with ptbkVersion
@@ -1032,124 +1105,6 @@
1032
1105
  * > ex port function validatePromptTemplatePipelineJson(ptp: unknown): asserts ptp is PromptTemplatePipelineJson {
1033
1106
  */
1034
1107
 
1035
- /**
1036
- * Prompt template pipeline is the **core concept of this library**.
1037
- * It represents a series of prompt templates chained together to form a pipeline / one big prompt template with input and result parameters.
1038
- *
1039
- * It can have 3 formats:
1040
- * - **.ptbk.md file** in custom markdown format described above
1041
- * - **JSON** format, parsed from the .ptbk.md file
1042
- * - _(this)_ **Object** which is created from JSON format and bound with tools around (but not the execution logic)
1043
- *
1044
- * @see https://github.com/webgptorg/promptbook#prompt-template-pipeline
1045
- */
1046
- var PromptTemplatePipeline = /** @class */ (function () {
1047
- function PromptTemplatePipeline(ptbkUrl, title, ptbkVersion, description, parameters, promptTemplates) {
1048
- this.ptbkUrl = ptbkUrl;
1049
- this.title = title;
1050
- this.ptbkVersion = ptbkVersion;
1051
- this.description = description;
1052
- this.parameters = parameters;
1053
- this.promptTemplates = promptTemplates;
1054
- if (promptTemplates.length === 0) {
1055
- throw new Error('Prompt template pipeline must have at least one prompt template');
1056
- }
1057
- }
1058
- /**
1059
- * Constructs PromptTemplatePipeline from any source
1060
- *
1061
- * Note: During the construction syntax and logic of source is validated
1062
- *
1063
- * @param source content of .ptbk.md or .ptbk.json file
1064
- * @returns PromptTemplatePipeline
1065
- */
1066
- PromptTemplatePipeline.fromSource = function (ptbkSource) {
1067
- if (typeof ptbkSource === 'string') {
1068
- return PromptTemplatePipeline.fromString(ptbkSource);
1069
- }
1070
- else {
1071
- return PromptTemplatePipeline.fromJson(ptbkSource);
1072
- }
1073
- };
1074
- /**
1075
- * Constructs PromptTemplatePipeline from markdown source
1076
- *
1077
- * Note: During the construction syntax and logic of source is validated
1078
- *
1079
- * @param ptbkString content of .ptbk.md file
1080
- * @returns PromptTemplatePipeline
1081
- */
1082
- PromptTemplatePipeline.fromString = function (ptbkString) {
1083
- var ptbkjson = promptTemplatePipelineStringToJson(ptbkString);
1084
- return PromptTemplatePipeline.fromJson(ptbkjson);
1085
- };
1086
- /**
1087
- * Constructs PromptTemplatePipeline from JSON source
1088
- *
1089
- * Note: During the construction the source is logic validated
1090
- *
1091
- * @param ptbkjson content of .ptbk.json file parsed into JSON
1092
- * @returns PromptTemplatePipeline
1093
- */
1094
- PromptTemplatePipeline.fromJson = function (ptbkjson) {
1095
- validatePromptTemplatePipelineJson(ptbkjson);
1096
- return new PromptTemplatePipeline(ptbkjson.ptbkUrl ? new URL(ptbkjson.ptbkUrl) : null, ptbkjson.title, ptbkjson.ptbkVersion, ptbkjson.description || null, Object.fromEntries(ptbkjson.parameters.map(function (parameter) { return [parameter.name, parameter]; })), ptbkjson.promptTemplates);
1097
- };
1098
- Object.defineProperty(PromptTemplatePipeline.prototype, "entryPromptTemplate", {
1099
- /**
1100
- * Returns the first prompt template in the pipeline
1101
- */
1102
- get: function () {
1103
- return this.promptTemplates[0];
1104
- },
1105
- enumerable: false,
1106
- configurable: true
1107
- });
1108
- /**
1109
- * Gets the parameter that is the result of given prompt template
1110
- */
1111
- PromptTemplatePipeline.prototype.getResultingParameter = function (promptTemplateName) {
1112
- var index = this.promptTemplates.findIndex(function (_a) {
1113
- var name = _a.name;
1114
- return name === promptTemplateName;
1115
- });
1116
- if (index === -1) {
1117
- throw new Error('Prompt template is not in this pipeline');
1118
- }
1119
- var resultingParameterName = this.promptTemplates[index].resultingParameterName;
1120
- var resultingParameter = this.parameters[resultingParameterName];
1121
- if (!resultingParameter) {
1122
- // <- TODO: [🥨] Make some NeverShouldHappenError
1123
- throw new Error("Resulting parameter of prompt template ".concat(promptTemplateName, " {").concat(resultingParameterName, "} is not defined"));
1124
- }
1125
- return resultingParameter;
1126
- };
1127
- /**
1128
- * Gets the following prompt template in the pipeline or null if there is no following prompt template and this is the last one
1129
- */
1130
- PromptTemplatePipeline.prototype.getFollowingPromptTemplate = function (promptTemplateName) {
1131
- var index = this.promptTemplates.findIndex(function (_a) {
1132
- var name = _a.name;
1133
- return name === promptTemplateName;
1134
- });
1135
- if (index === -1) {
1136
- throw new Error('Prompt template is not in this pipeline');
1137
- }
1138
- if (index === this.promptTemplates.length - 1) {
1139
- return null;
1140
- }
1141
- return this.promptTemplates[index + 1];
1142
- };
1143
- return PromptTemplatePipeline;
1144
- }());
1145
- /**
1146
- * TODO: !! [👐][🧠] Split of PromptTemplatePipeline,PromptTemplatePipelineLibrary between interface and class
1147
- * TODO: !! [👐] Make parameters and promptTemplates private WHEN split between interface and class
1148
- * TODO: !! Add generic type for entry and result parameters
1149
- * TODO: Can be Array elegantly typed such as it must have at least one element?
1150
- * TODO: [🧠] Each PromptTemplatePipeline should have its unique hash to be able to compare them and execute on server ONLY the desired ones
1151
- */
1152
-
1153
1108
  /**
1154
1109
  * Counts number of characters in the text
1155
1110
  */
@@ -1342,11 +1297,11 @@
1342
1297
  finally { if (e_1) throw e_1.error; }
1343
1298
  }
1344
1299
  }
1345
- // Check if there are parameters that are not closed properly
1300
+ // [💫] Check if there are parameters that are not closed properly
1346
1301
  if (/{\w+$/.test(replacedTemplate)) {
1347
1302
  throw new Error('Parameter is not closed');
1348
1303
  }
1349
- // Check if there are parameters that are not opened properly
1304
+ // [💫] Check if there are parameters that are not opened properly
1350
1305
  if (/^\w+}/.test(replacedTemplate)) {
1351
1306
  throw new Error('Parameter is not opened');
1352
1307
  }
@@ -1379,370 +1334,408 @@
1379
1334
  var _this = this;
1380
1335
  var ptp = options.ptp, tools = options.tools, _a = options.settings, settings = _a === void 0 ? {} : _a;
1381
1336
  var _b = settings.maxExecutionAttempts, maxExecutionAttempts = _b === void 0 ? 3 : _b;
1337
+ validatePromptTemplatePipelineJson(ptp);
1382
1338
  var ptpExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
1383
- var parametersToPass, currentTemplate, executionReport, priority, _loop_1, error_1;
1384
- var _a;
1385
- return __generator(this, function (_b) {
1386
- switch (_b.label) {
1339
+ function executeSingleTemplate(currentTemplate) {
1340
+ return __awaiter(this, void 0, void 0, function () {
1341
+ var name, title, priority, prompt, chatThread, completionResult, result, resultString, expectError, scriptExecutionErrors, maxAttempts, jokers, attempt, isJokerAttempt, joker, _a, _b, _c, _d, scriptTools, error_2, e_1_1, _e, _f, functionName, postprocessingError, _g, _h, scriptTools, error_3, e_2_1, e_3_1, _j, _k, _l, unit, _m, max, min, amount, error_4;
1342
+ var e_1, _o, e_3, _p, e_2, _q, e_4, _r, _s;
1343
+ return __generator(this, function (_t) {
1344
+ switch (_t.label) {
1345
+ case 0:
1346
+ console.log('!!!! executeSingleTemplate', currentTemplate.title);
1347
+ name = "ptp-executor-frame-".concat(currentTemplate.name);
1348
+ title = removeEmojis(removeMarkdownFormatting(currentTemplate.title));
1349
+ priority = ptp.promptTemplates.indexOf(currentTemplate);
1350
+ if (!onProgress) return [3 /*break*/, 2];
1351
+ return [4 /*yield*/, onProgress({
1352
+ name: name,
1353
+ title: title,
1354
+ isStarted: false,
1355
+ isDone: false,
1356
+ executionType: currentTemplate.executionType,
1357
+ parameterName: currentTemplate.resultingParameterName,
1358
+ parameterValue: null,
1359
+ })];
1360
+ case 1:
1361
+ _t.sent();
1362
+ _t.label = 2;
1363
+ case 2:
1364
+ result = null;
1365
+ resultString = null;
1366
+ expectError = null;
1367
+ maxAttempts = currentTemplate.executionType === 'PROMPT_DIALOG' ? Infinity : maxExecutionAttempts;
1368
+ jokers = currentTemplate.jokers || [];
1369
+ attempt = -jokers.length;
1370
+ _t.label = 3;
1371
+ case 3:
1372
+ if (!(attempt < maxAttempts)) return [3 /*break*/, 49];
1373
+ isJokerAttempt = attempt < 0;
1374
+ joker = jokers[jokers.length + attempt];
1375
+ if (isJokerAttempt && !joker) {
1376
+ throw new Error("Joker not found in attempt ".concat(attempt));
1377
+ // <- TODO: [🥨] Make some NeverShouldHappenError
1378
+ }
1379
+ result = null;
1380
+ resultString = null;
1381
+ expectError = null;
1382
+ if (isJokerAttempt) {
1383
+ if (typeof parametersToPass[joker] === 'undefined') {
1384
+ throw new Error("Joker parameter {".concat(joker, "} not defined"));
1385
+ }
1386
+ resultString = parametersToPass[joker];
1387
+ }
1388
+ _t.label = 4;
1389
+ case 4:
1390
+ _t.trys.push([4, 45, 46, 47]);
1391
+ if (!!isJokerAttempt) return [3 /*break*/, 27];
1392
+ _a = currentTemplate.executionType;
1393
+ switch (_a) {
1394
+ case 'SIMPLE_TEMPLATE': return [3 /*break*/, 5];
1395
+ case 'PROMPT_TEMPLATE': return [3 /*break*/, 6];
1396
+ case 'SCRIPT': return [3 /*break*/, 13];
1397
+ case 'PROMPT_DIALOG': return [3 /*break*/, 24];
1398
+ }
1399
+ return [3 /*break*/, 26];
1400
+ case 5:
1401
+ resultString = replaceParameters(currentTemplate.content, parametersToPass);
1402
+ return [3 /*break*/, 27];
1403
+ case 6:
1404
+ prompt = {
1405
+ title: currentTemplate.title,
1406
+ ptbkUrl: "".concat(ptp.ptbkUrl
1407
+ ? ptp.ptbkUrl
1408
+ : 'anonymous' /* <- [🧠] !!! How to deal with anonymous PTPs, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(currentTemplate.name),
1409
+ parameters: parametersToPass,
1410
+ content: replaceParameters(currentTemplate.content, parametersToPass) /* <- [2] */,
1411
+ modelRequirements: currentTemplate.modelRequirements,
1412
+ };
1413
+ _b = currentTemplate.modelRequirements.modelVariant;
1414
+ switch (_b) {
1415
+ case 'CHAT': return [3 /*break*/, 7];
1416
+ case 'COMPLETION': return [3 /*break*/, 9];
1417
+ }
1418
+ return [3 /*break*/, 11];
1419
+ case 7: return [4 /*yield*/, tools.natural.gptChat(prompt)];
1420
+ case 8:
1421
+ chatThread = _t.sent();
1422
+ // TODO: [🍬] Destroy chatThread
1423
+ result = chatThread;
1424
+ resultString = chatThread.content;
1425
+ return [3 /*break*/, 12];
1426
+ case 9: return [4 /*yield*/, tools.natural.gptComplete(prompt)];
1427
+ case 10:
1428
+ completionResult = _t.sent();
1429
+ result = completionResult;
1430
+ resultString = completionResult.content;
1431
+ return [3 /*break*/, 12];
1432
+ case 11: throw new Error("Unknown model variant \"".concat(currentTemplate.modelRequirements.modelVariant, "\""));
1433
+ case 12: return [3 /*break*/, 27];
1434
+ case 13:
1435
+ if (tools.script.length === 0) {
1436
+ throw new Error('No script execution tools are available');
1437
+ }
1438
+ if (!currentTemplate.contentLanguage) {
1439
+ throw new Error("Script language is not defined for prompt template \"".concat(currentTemplate.name, "\""));
1440
+ }
1441
+ // TODO: DRY [1]
1442
+ scriptExecutionErrors = [];
1443
+ _t.label = 14;
1444
+ case 14:
1445
+ _t.trys.push([14, 21, 22, 23]);
1446
+ _c = (e_1 = void 0, __values(tools.script)), _d = _c.next();
1447
+ _t.label = 15;
1448
+ case 15:
1449
+ if (!!_d.done) return [3 /*break*/, 20];
1450
+ scriptTools = _d.value;
1451
+ _t.label = 16;
1452
+ case 16:
1453
+ _t.trys.push([16, 18, , 19]);
1454
+ return [4 /*yield*/, scriptTools.execute({
1455
+ scriptLanguage: currentTemplate.contentLanguage,
1456
+ script: currentTemplate.content,
1457
+ parameters: parametersToPass,
1458
+ })];
1459
+ case 17:
1460
+ resultString = _t.sent();
1461
+ return [3 /*break*/, 20];
1462
+ case 18:
1463
+ error_2 = _t.sent();
1464
+ if (!(error_2 instanceof Error)) {
1465
+ throw error_2;
1466
+ }
1467
+ scriptExecutionErrors.push(error_2);
1468
+ return [3 /*break*/, 19];
1469
+ case 19:
1470
+ _d = _c.next();
1471
+ return [3 /*break*/, 15];
1472
+ case 20: return [3 /*break*/, 23];
1473
+ case 21:
1474
+ e_1_1 = _t.sent();
1475
+ e_1 = { error: e_1_1 };
1476
+ return [3 /*break*/, 23];
1477
+ case 22:
1478
+ try {
1479
+ if (_d && !_d.done && (_o = _c.return)) _o.call(_c);
1480
+ }
1481
+ finally { if (e_1) throw e_1.error; }
1482
+ return [7 /*endfinally*/];
1483
+ case 23:
1484
+ if (resultString) {
1485
+ return [3 /*break*/, 27];
1486
+ }
1487
+ if (scriptExecutionErrors.length === 1) {
1488
+ throw scriptExecutionErrors[0];
1489
+ }
1490
+ else {
1491
+ throw new Error(spaceTrim__default["default"](function (block) { return "\n Script execution failed ".concat(scriptExecutionErrors.length, " times\n\n ").concat(block(scriptExecutionErrors
1492
+ .map(function (error) { return '- ' + error.message; })
1493
+ .join('\n\n')), "\n "); }));
1494
+ }
1495
+ case 24: return [4 /*yield*/, tools.userInterface.promptDialog({
1496
+ promptTitle: currentTemplate.title,
1497
+ promptMessage: replaceParameters(currentTemplate.description || '', parametersToPass),
1498
+ defaultValue: replaceParameters(currentTemplate.content, parametersToPass),
1499
+ // TODO: [🧠] !! Figure out how to define placeholder in .ptbk.md file
1500
+ placeholder: undefined,
1501
+ priority: priority /* <- TODO: !!!! Is it ending with 0 */,
1502
+ })];
1503
+ case 25:
1504
+ // TODO: !!!! When making next attempt for `PROMPT DIALOG`, preserve the previous user input
1505
+ resultString = _t.sent();
1506
+ return [3 /*break*/, 27];
1507
+ case 26: throw new Error(
1508
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1509
+ "Unknown execution type \"".concat(currentTemplate.executionType, "\""));
1510
+ case 27:
1511
+ if (!(!isJokerAttempt && currentTemplate.postprocessing)) return [3 /*break*/, 44];
1512
+ _t.label = 28;
1513
+ case 28:
1514
+ _t.trys.push([28, 42, 43, 44]);
1515
+ _e = (e_3 = void 0, __values(currentTemplate.postprocessing)), _f = _e.next();
1516
+ _t.label = 29;
1517
+ case 29:
1518
+ if (!!_f.done) return [3 /*break*/, 41];
1519
+ functionName = _f.value;
1520
+ // TODO: DRY [1]
1521
+ scriptExecutionErrors = [];
1522
+ postprocessingError = null;
1523
+ _t.label = 30;
1524
+ case 30:
1525
+ _t.trys.push([30, 37, 38, 39]);
1526
+ _g = (e_2 = void 0, __values(tools.script)), _h = _g.next();
1527
+ _t.label = 31;
1528
+ case 31:
1529
+ if (!!_h.done) return [3 /*break*/, 36];
1530
+ scriptTools = _h.value;
1531
+ _t.label = 32;
1532
+ case 32:
1533
+ _t.trys.push([32, 34, , 35]);
1534
+ return [4 /*yield*/, scriptTools.execute({
1535
+ scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
1536
+ script: "".concat(functionName, "(resultString)"),
1537
+ parameters: __assign(__assign({}, parametersToPass), { resultString: resultString || '' }),
1538
+ })];
1539
+ case 33:
1540
+ resultString = _t.sent();
1541
+ postprocessingError = null;
1542
+ return [3 /*break*/, 36];
1543
+ case 34:
1544
+ error_3 = _t.sent();
1545
+ if (!(error_3 instanceof Error)) {
1546
+ throw error_3;
1547
+ }
1548
+ postprocessingError = error_3;
1549
+ scriptExecutionErrors.push(error_3);
1550
+ return [3 /*break*/, 35];
1551
+ case 35:
1552
+ _h = _g.next();
1553
+ return [3 /*break*/, 31];
1554
+ case 36: return [3 /*break*/, 39];
1555
+ case 37:
1556
+ e_2_1 = _t.sent();
1557
+ e_2 = { error: e_2_1 };
1558
+ return [3 /*break*/, 39];
1559
+ case 38:
1560
+ try {
1561
+ if (_h && !_h.done && (_q = _g.return)) _q.call(_g);
1562
+ }
1563
+ finally { if (e_2) throw e_2.error; }
1564
+ return [7 /*endfinally*/];
1565
+ case 39:
1566
+ if (postprocessingError) {
1567
+ throw postprocessingError;
1568
+ }
1569
+ _t.label = 40;
1570
+ case 40:
1571
+ _f = _e.next();
1572
+ return [3 /*break*/, 29];
1573
+ case 41: return [3 /*break*/, 44];
1574
+ case 42:
1575
+ e_3_1 = _t.sent();
1576
+ e_3 = { error: e_3_1 };
1577
+ return [3 /*break*/, 44];
1578
+ case 43:
1579
+ try {
1580
+ if (_f && !_f.done && (_p = _e.return)) _p.call(_e);
1581
+ }
1582
+ finally { if (e_3) throw e_3.error; }
1583
+ return [7 /*endfinally*/];
1584
+ case 44:
1585
+ if (currentTemplate.expectFormat) {
1586
+ if (currentTemplate.expectFormat === 'JSON') {
1587
+ if (!isValidJsonString(resultString || '')) {
1588
+ throw new ExpectError('Expected valid JSON string');
1589
+ }
1590
+ }
1591
+ }
1592
+ if (currentTemplate.expectAmount) {
1593
+ try {
1594
+ for (_j = (e_4 = void 0, __values(Object.entries(currentTemplate.expectAmount))), _k = _j.next(); !_k.done; _k = _j.next()) {
1595
+ _l = __read(_k.value, 2), unit = _l[0], _m = _l[1], max = _m.max, min = _m.min;
1596
+ amount = CountUtils[unit.toUpperCase()](resultString || '');
1597
+ if (min && amount < min) {
1598
+ throw new ExpectError("Expected at least ".concat(min, " ").concat(unit, " but got ").concat(amount));
1599
+ } /* not else */
1600
+ if (max && amount > max) {
1601
+ throw new ExpectError("Expected at most ".concat(max, " ").concat(unit, " but got ").concat(amount));
1602
+ }
1603
+ }
1604
+ }
1605
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
1606
+ finally {
1607
+ try {
1608
+ if (_k && !_k.done && (_r = _j.return)) _r.call(_j);
1609
+ }
1610
+ finally { if (e_4) throw e_4.error; }
1611
+ }
1612
+ }
1613
+ return [3 /*break*/, 49];
1614
+ case 45:
1615
+ error_4 = _t.sent();
1616
+ if (!(error_4 instanceof ExpectError)) {
1617
+ throw error_4;
1618
+ }
1619
+ expectError = error_4;
1620
+ return [3 /*break*/, 47];
1621
+ case 46:
1622
+ if (!isJokerAttempt &&
1623
+ currentTemplate.executionType === 'PROMPT_TEMPLATE' &&
1624
+ prompt
1625
+ // <- Note: [2] When some expected parameter is not defined, error will occur in replaceParameters
1626
+ // In that case we don’t want to make a report about it because it’s not a natural execution error
1627
+ ) {
1628
+ // TODO: [🧠] Maybe put other executionTypes into report
1629
+ executionReport.promptExecutions.push({
1630
+ prompt: {
1631
+ title: currentTemplate.title /* <- Note: If title in promptbook contains emojis, pass it innto report */,
1632
+ content: prompt.content,
1633
+ modelRequirements: prompt.modelRequirements,
1634
+ // <- Note: Do want to pass ONLY wanted information to the report
1635
+ },
1636
+ result: result || undefined,
1637
+ error: expectError || undefined,
1638
+ });
1639
+ }
1640
+ return [7 /*endfinally*/];
1641
+ case 47:
1642
+ if (expectError !== null && attempt === maxAttempts - 1) {
1643
+ throw new Error(spaceTrim__default["default"](function (block) { return "\n Natural execution failed ".concat(settings.maxExecutionAttempts, "x\n\n ").concat(block((expectError === null || expectError === void 0 ? void 0 : expectError.message) || ''), "\n "); }));
1644
+ }
1645
+ _t.label = 48;
1646
+ case 48:
1647
+ attempt++;
1648
+ return [3 /*break*/, 3];
1649
+ case 49:
1650
+ if (resultString === null) {
1651
+ // <- TODO: [🥨] Make some NeverShouldHappenError
1652
+ throw new Error('Something went wrong and prompt result is null');
1653
+ }
1654
+ if (onProgress) {
1655
+ onProgress({
1656
+ name: name,
1657
+ title: title,
1658
+ isStarted: true,
1659
+ isDone: true,
1660
+ executionType: currentTemplate.executionType,
1661
+ parameterName: currentTemplate.resultingParameterName,
1662
+ parameterValue: resultString,
1663
+ });
1664
+ }
1665
+ parametersToPass = __assign(__assign({}, parametersToPass), (_s = {}, _s[currentTemplate.resultingParameterName] = resultString /* <- Note: Not need to detect parameter collision here because PromptTemplatePipeline checks logic consistency during construction */, _s));
1666
+ return [2 /*return*/];
1667
+ }
1668
+ });
1669
+ });
1670
+ }
1671
+ var parametersToPass, executionReport, resovedParameters_1, unresovedTemplates, works_1, _loop_1, error_1;
1672
+ return __generator(this, function (_a) {
1673
+ switch (_a.label) {
1387
1674
  case 0:
1388
1675
  parametersToPass = inputParameters;
1389
- currentTemplate = ptp.entryPromptTemplate;
1390
1676
  executionReport = {
1391
- ptbkUrl: ((_a = ptp.ptbkUrl) === null || _a === void 0 ? void 0 : _a.href) || undefined,
1392
- title: ptp.title || undefined,
1677
+ ptbkUrl: ptp.ptbkUrl,
1678
+ title: ptp.title,
1393
1679
  ptbkUsedVersion: PTBK_VERSION,
1394
- ptbkRequestedVersion: ptp.ptbkVersion || undefined,
1395
- description: ptp.description || undefined,
1680
+ ptbkRequestedVersion: ptp.ptbkVersion,
1681
+ description: ptp.description,
1396
1682
  promptExecutions: [],
1397
1683
  };
1398
- priority = ptp.promptTemplates.length;
1399
- _b.label = 1;
1684
+ _a.label = 1;
1400
1685
  case 1:
1401
- _b.trys.push([1, 5, , 6]);
1686
+ _a.trys.push([1, 6, , 7]);
1687
+ resovedParameters_1 = ptp.parameters
1688
+ .filter(function (_a) {
1689
+ var isInput = _a.isInput;
1690
+ return isInput;
1691
+ })
1692
+ .map(function (_a) {
1693
+ var name = _a.name;
1694
+ return name;
1695
+ });
1696
+ unresovedTemplates = __spreadArray([], __read(ptp.promptTemplates), false);
1697
+ works_1 = [];
1402
1698
  _loop_1 = function () {
1403
- var resultingParameter, name_1, title, prompt_1, chatThread, completionResult, result, resultString, expectError, scriptExecutionErrors, maxAttempts, jokers, attempt, isJokerAttempt, joker, _c, _d, _e, _f, scriptTools, error_2, e_1_1, _g, _h, functionName, postprocessingError, _j, _k, scriptTools, error_3, e_2_1, e_3_1, _l, _m, _o, unit, _p, max, min, amount, error_4;
1404
- var e_1, _q, e_3, _r, e_2, _s, e_4, _t, _u;
1405
- return __generator(this, function (_v) {
1406
- switch (_v.label) {
1699
+ var currentTemplate, work_1;
1700
+ return __generator(this, function (_b) {
1701
+ switch (_b.label) {
1407
1702
  case 0:
1408
- priority--;
1409
- resultingParameter = ptp.getResultingParameter(currentTemplate.name);
1410
- name_1 = "ptp-executor-frame-".concat(currentTemplate.name);
1411
- title = removeEmojis(removeMarkdownFormatting(currentTemplate.title));
1412
- if (!onProgress) return [3 /*break*/, 2];
1413
- return [4 /*yield*/, onProgress({
1414
- name: name_1,
1415
- title: title,
1416
- isStarted: false,
1417
- isDone: false,
1418
- executionType: currentTemplate.executionType,
1419
- parameterName: resultingParameter.name,
1420
- parameterValue: null,
1421
- })];
1703
+ currentTemplate = unresovedTemplates.find(function (template) {
1704
+ return template.dependentParameterNames.every(function (name) { return resovedParameters_1.includes(name); });
1705
+ });
1706
+ if (!!currentTemplate) return [3 /*break*/, 2];
1707
+ /* [5] */ return [4 /*yield*/, Promise.race(works_1)];
1422
1708
  case 1:
1423
- _v.sent();
1424
- _v.label = 2;
1425
- case 2:
1426
- prompt_1 = void 0;
1427
- chatThread = void 0;
1428
- completionResult = void 0;
1429
- result = null;
1430
- resultString = null;
1431
- expectError = null;
1432
- maxAttempts = currentTemplate.executionType === 'PROMPT_DIALOG' ? Infinity : maxExecutionAttempts;
1433
- jokers = currentTemplate.jokers || [];
1434
- attempt = -jokers.length;
1435
- _v.label = 3;
1436
- case 3:
1437
- if (!(attempt < maxAttempts)) return [3 /*break*/, 49];
1438
- isJokerAttempt = attempt < 0;
1439
- joker = jokers[jokers.length + attempt];
1440
- if (isJokerAttempt && !joker) {
1441
- throw new Error("Joker not found in attempt ".concat(attempt));
1442
- // <- TODO: [🥨] Make some NeverShouldHappenError
1443
- }
1444
- result = null;
1445
- resultString = null;
1446
- expectError = null;
1447
- if (isJokerAttempt) {
1448
- if (typeof parametersToPass[joker] === 'undefined') {
1449
- throw new Error("Joker parameter {".concat(joker, "} not defined"));
1450
- }
1451
- resultString = parametersToPass[joker];
1452
- }
1453
- _v.label = 4;
1454
- case 4:
1455
- _v.trys.push([4, 45, 46, 47]);
1456
- if (!!isJokerAttempt) return [3 /*break*/, 27];
1457
- _c = currentTemplate.executionType;
1458
- switch (_c) {
1459
- case 'SIMPLE_TEMPLATE': return [3 /*break*/, 5];
1460
- case 'PROMPT_TEMPLATE': return [3 /*break*/, 6];
1461
- case 'SCRIPT': return [3 /*break*/, 13];
1462
- case 'PROMPT_DIALOG': return [3 /*break*/, 24];
1463
- }
1464
- return [3 /*break*/, 26];
1465
- case 5:
1466
- resultString = replaceParameters(currentTemplate.content, parametersToPass);
1467
- return [3 /*break*/, 27];
1468
- case 6:
1469
- prompt_1 = {
1470
- title: currentTemplate.title,
1471
- ptbkUrl: "".concat(ptp.ptbkUrl
1472
- ? ptp.ptbkUrl.href
1473
- : 'anonymous' /* <- [🧠] !!! How to deal with anonymous PTPs, do here some auto-url like SHA-256 based ad-hoc identifier? */, "#").concat(currentTemplate.name),
1474
- parameters: parametersToPass,
1475
- content: replaceParameters(currentTemplate.content, parametersToPass) /* <- [2] */,
1476
- modelRequirements: currentTemplate.modelRequirements,
1477
- };
1478
- _d = currentTemplate.modelRequirements.modelVariant;
1479
- switch (_d) {
1480
- case 'CHAT': return [3 /*break*/, 7];
1481
- case 'COMPLETION': return [3 /*break*/, 9];
1482
- }
1483
- return [3 /*break*/, 11];
1484
- case 7: return [4 /*yield*/, tools.natural.gptChat(prompt_1)];
1485
- case 8:
1486
- chatThread = _v.sent();
1487
- // TODO: [🍬] Destroy chatThread
1488
- result = chatThread;
1489
- resultString = chatThread.content;
1490
- return [3 /*break*/, 12];
1491
- case 9: return [4 /*yield*/, tools.natural.gptComplete(prompt_1)];
1492
- case 10:
1493
- completionResult = _v.sent();
1494
- result = completionResult;
1495
- resultString = completionResult.content;
1496
- return [3 /*break*/, 12];
1497
- case 11: throw new Error("Unknown model variant \"".concat(currentTemplate.modelRequirements.modelVariant, "\""));
1498
- case 12: return [3 /*break*/, 27];
1499
- case 13:
1500
- if (tools.script.length === 0) {
1501
- throw new Error('No script execution tools are available');
1502
- }
1503
- if (!currentTemplate.contentLanguage) {
1504
- throw new Error("Script language is not defined for prompt template \"".concat(currentTemplate.name, "\""));
1505
- }
1506
- // TODO: DRY [1]
1507
- scriptExecutionErrors = [];
1508
- _v.label = 14;
1509
- case 14:
1510
- _v.trys.push([14, 21, 22, 23]);
1511
- _e = (e_1 = void 0, __values(tools.script)), _f = _e.next();
1512
- _v.label = 15;
1513
- case 15:
1514
- if (!!_f.done) return [3 /*break*/, 20];
1515
- scriptTools = _f.value;
1516
- _v.label = 16;
1517
- case 16:
1518
- _v.trys.push([16, 18, , 19]);
1519
- return [4 /*yield*/, scriptTools.execute({
1520
- scriptLanguage: currentTemplate.contentLanguage,
1521
- script: currentTemplate.content,
1522
- parameters: parametersToPass,
1523
- })];
1524
- case 17:
1525
- resultString = _v.sent();
1526
- return [3 /*break*/, 20];
1527
- case 18:
1528
- error_2 = _v.sent();
1529
- if (!(error_2 instanceof Error)) {
1530
- throw error_2;
1531
- }
1532
- scriptExecutionErrors.push(error_2);
1533
- return [3 /*break*/, 19];
1534
- case 19:
1535
- _f = _e.next();
1536
- return [3 /*break*/, 15];
1537
- case 20: return [3 /*break*/, 23];
1538
- case 21:
1539
- e_1_1 = _v.sent();
1540
- e_1 = { error: e_1_1 };
1541
- return [3 /*break*/, 23];
1542
- case 22:
1543
- try {
1544
- if (_f && !_f.done && (_q = _e.return)) _q.call(_e);
1545
- }
1546
- finally { if (e_1) throw e_1.error; }
1547
- return [7 /*endfinally*/];
1548
- case 23:
1549
- if (resultString) {
1550
- return [3 /*break*/, 27];
1551
- }
1552
- if (scriptExecutionErrors.length === 1) {
1553
- throw scriptExecutionErrors[0];
1554
- }
1555
- else {
1556
- throw new Error(spaceTrim__default["default"](function (block) { return "\n Script execution failed ".concat(scriptExecutionErrors.length, " times\n\n ").concat(block(scriptExecutionErrors
1557
- .map(function (error) { return '- ' + error.message; })
1558
- .join('\n\n')), "\n "); }));
1559
- }
1560
- case 24: return [4 /*yield*/, tools.userInterface.promptDialog({
1561
- promptTitle: currentTemplate.title,
1562
- promptMessage: replaceParameters(currentTemplate.description || '', parametersToPass),
1563
- defaultValue: replaceParameters(currentTemplate.content, parametersToPass),
1564
- // TODO: [🧠] !! Figure out how to define placeholder in .ptbk.md file
1565
- placeholder: undefined,
1566
- priority: priority /* <- TODO: !!!! Is it ending with 0 */,
1567
- })];
1568
- case 25:
1569
- // TODO: !!!! When making next attempt for `PROMPT DIALOG`, preserve the previous user input
1570
- resultString = _v.sent();
1571
- return [3 /*break*/, 27];
1572
- case 26: throw new Error(
1573
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1574
- "Unknown execution type \"".concat(currentTemplate.executionType, "\""));
1575
- case 27:
1576
- if (!(!isJokerAttempt && currentTemplate.postprocessing)) return [3 /*break*/, 44];
1577
- _v.label = 28;
1578
- case 28:
1579
- _v.trys.push([28, 42, 43, 44]);
1580
- _g = (e_3 = void 0, __values(currentTemplate.postprocessing)), _h = _g.next();
1581
- _v.label = 29;
1582
- case 29:
1583
- if (!!_h.done) return [3 /*break*/, 41];
1584
- functionName = _h.value;
1585
- // TODO: DRY [1]
1586
- scriptExecutionErrors = [];
1587
- postprocessingError = null;
1588
- _v.label = 30;
1589
- case 30:
1590
- _v.trys.push([30, 37, 38, 39]);
1591
- _j = (e_2 = void 0, __values(tools.script)), _k = _j.next();
1592
- _v.label = 31;
1593
- case 31:
1594
- if (!!_k.done) return [3 /*break*/, 36];
1595
- scriptTools = _k.value;
1596
- _v.label = 32;
1597
- case 32:
1598
- _v.trys.push([32, 34, , 35]);
1599
- return [4 /*yield*/, scriptTools.execute({
1600
- scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
1601
- script: "".concat(functionName, "(resultString)"),
1602
- parameters: __assign(__assign({}, parametersToPass), { resultString: resultString || '' }),
1603
- })];
1604
- case 33:
1605
- resultString = _v.sent();
1606
- postprocessingError = null;
1607
- return [3 /*break*/, 36];
1608
- case 34:
1609
- error_3 = _v.sent();
1610
- if (!(error_3 instanceof Error)) {
1611
- throw error_3;
1612
- }
1613
- postprocessingError = error_3;
1614
- scriptExecutionErrors.push(error_3);
1615
- return [3 /*break*/, 35];
1616
- case 35:
1617
- _k = _j.next();
1618
- return [3 /*break*/, 31];
1619
- case 36: return [3 /*break*/, 39];
1620
- case 37:
1621
- e_2_1 = _v.sent();
1622
- e_2 = { error: e_2_1 };
1623
- return [3 /*break*/, 39];
1624
- case 38:
1625
- try {
1626
- if (_k && !_k.done && (_s = _j.return)) _s.call(_j);
1627
- }
1628
- finally { if (e_2) throw e_2.error; }
1629
- return [7 /*endfinally*/];
1630
- case 39:
1631
- if (postprocessingError) {
1632
- throw postprocessingError;
1633
- }
1634
- _v.label = 40;
1635
- case 40:
1636
- _h = _g.next();
1637
- return [3 /*break*/, 29];
1638
- case 41: return [3 /*break*/, 44];
1639
- case 42:
1640
- e_3_1 = _v.sent();
1641
- e_3 = { error: e_3_1 };
1642
- return [3 /*break*/, 44];
1643
- case 43:
1644
- try {
1645
- if (_h && !_h.done && (_r = _g.return)) _r.call(_g);
1646
- }
1647
- finally { if (e_3) throw e_3.error; }
1648
- return [7 /*endfinally*/];
1649
- case 44:
1650
- if (currentTemplate.expectFormat) {
1651
- if (currentTemplate.expectFormat === 'JSON') {
1652
- if (!isValidJsonString(resultString || '')) {
1653
- throw new ExpectError('Expected valid JSON string');
1654
- }
1655
- }
1656
- }
1657
- if (currentTemplate.expectAmount) {
1658
- try {
1659
- for (_l = (e_4 = void 0, __values(Object.entries(currentTemplate.expectAmount))), _m = _l.next(); !_m.done; _m = _l.next()) {
1660
- _o = __read(_m.value, 2), unit = _o[0], _p = _o[1], max = _p.max, min = _p.min;
1661
- amount = CountUtils[unit.toUpperCase()](resultString || '');
1662
- if (min && amount < min) {
1663
- throw new ExpectError("Expected at least ".concat(min, " ").concat(unit, " but got ").concat(amount));
1664
- } /* not else */
1665
- if (max && amount > max) {
1666
- throw new ExpectError("Expected at most ".concat(max, " ").concat(unit, " but got ").concat(amount));
1667
- }
1668
- }
1669
- }
1670
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
1671
- finally {
1672
- try {
1673
- if (_m && !_m.done && (_t = _l.return)) _t.call(_l);
1674
- }
1675
- finally { if (e_4) throw e_4.error; }
1676
- }
1677
- }
1678
- return [3 /*break*/, 49];
1679
- case 45:
1680
- error_4 = _v.sent();
1681
- if (!(error_4 instanceof ExpectError)) {
1682
- throw error_4;
1683
- }
1684
- expectError = error_4;
1685
- return [3 /*break*/, 47];
1686
- case 46:
1687
- if (!isJokerAttempt &&
1688
- currentTemplate.executionType === 'PROMPT_TEMPLATE' &&
1689
- prompt_1
1690
- // <- Note: [2] When some expected parameter is not defined, error will occur in replaceParameters
1691
- // In that case we don’t want to make a report about it because it’s not a natural execution error
1692
- ) {
1693
- // TODO: [🧠] Maybe put other executionTypes into report
1694
- executionReport.promptExecutions.push({
1695
- prompt: {
1696
- title: currentTemplate.title /* <- Note: If title in promptbook contains emojis, pass it innto report */,
1697
- content: prompt_1.content,
1698
- modelRequirements: prompt_1.modelRequirements,
1699
- // <- Note: Do want to pass ONLY wanted information to the report
1700
- },
1701
- result: result || undefined,
1702
- error: expectError || undefined,
1703
- });
1704
- }
1705
- return [7 /*endfinally*/];
1706
- case 47:
1707
- if (expectError !== null && attempt === maxAttempts - 1) {
1708
- throw new Error(spaceTrim__default["default"](function (block) { return "\n Natural execution failed ".concat(settings.maxExecutionAttempts, "x\n\n ").concat(block((expectError === null || expectError === void 0 ? void 0 : expectError.message) || ''), "\n "); }));
1709
- }
1710
- _v.label = 48;
1711
- case 48:
1712
- attempt++;
1709
+ /* [5] */ _b.sent();
1713
1710
  return [3 /*break*/, 3];
1714
- case 49:
1715
- if (resultString === null) {
1716
- // <- TODO: [🥨] Make some NeverShouldHappenError
1717
- throw new Error('Something went wrong and prompt result is null');
1718
- }
1719
- if (onProgress) {
1720
- onProgress({
1721
- name: name_1,
1722
- title: title,
1723
- isStarted: true,
1724
- isDone: true,
1725
- executionType: currentTemplate.executionType,
1726
- parameterName: resultingParameter.name,
1727
- parameterValue: resultString,
1728
- });
1729
- }
1730
- parametersToPass = __assign(__assign({}, parametersToPass), (_u = {}, _u[resultingParameter.name] = resultString /* <- Note: Not need to detect parameter collision here because PromptTemplatePipeline checks logic consistency during construction */, _u));
1731
- currentTemplate = ptp.getFollowingPromptTemplate(currentTemplate.name);
1732
- return [2 /*return*/];
1711
+ case 2:
1712
+ unresovedTemplates = unresovedTemplates.filter(function (template) { return template !== currentTemplate; });
1713
+ work_1 = executeSingleTemplate(currentTemplate)
1714
+ .then(function () {
1715
+ resovedParameters_1 = resovedParameters_1.filter(function (name) { return !currentTemplate.dependentParameterNames.includes(name); });
1716
+ })
1717
+ .then(function () {
1718
+ works_1 = works_1.filter(function (w) { return w !== work_1; });
1719
+ });
1720
+ works_1.push(work_1);
1721
+ _b.label = 3;
1722
+ case 3: return [2 /*return*/];
1733
1723
  }
1734
1724
  });
1735
1725
  };
1736
- _b.label = 2;
1726
+ _a.label = 2;
1737
1727
  case 2:
1738
- if (!(currentTemplate !== null)) return [3 /*break*/, 4];
1728
+ if (!(unresovedTemplates.length > 0)) return [3 /*break*/, 4];
1739
1729
  return [5 /*yield**/, _loop_1()];
1740
1730
  case 3:
1741
- _b.sent();
1731
+ _a.sent();
1742
1732
  return [3 /*break*/, 2];
1743
- case 4: return [3 /*break*/, 6];
1733
+ case 4: return [4 /*yield*/, Promise.all(works_1)];
1744
1734
  case 5:
1745
- error_1 = _b.sent();
1735
+ _a.sent();
1736
+ return [3 /*break*/, 7];
1737
+ case 6:
1738
+ error_1 = _a.sent();
1746
1739
  if (!(error_1 instanceof Error)) {
1747
1740
  throw error_1;
1748
1741
  }
@@ -1752,7 +1745,7 @@
1752
1745
  executionReport: executionReport,
1753
1746
  outputParameters: parametersToPass,
1754
1747
  }];
1755
- case 6: return [2 /*return*/, {
1748
+ case 7: return [2 /*return*/, {
1756
1749
  isSuccessful: true,
1757
1750
  errors: [],
1758
1751
  executionReport: executionReport,
@@ -1798,7 +1791,15 @@
1798
1791
  try {
1799
1792
  for (var _b = __values(Object.entries(ptbkSources)), _c = _b.next(); !_c.done; _c = _b.next()) {
1800
1793
  var _d = __read(_c.value, 2), name_1 = _d[0], source = _d[1];
1801
- library[name_1] = PromptTemplatePipeline.fromSource(source);
1794
+ if (typeof source === 'string') {
1795
+ // Note: When directly creating from string, no need to validate the source
1796
+ // The validation is performed always before execution
1797
+ library[name_1] = promptTemplatePipelineStringToJson(source);
1798
+ }
1799
+ else {
1800
+ validatePromptTemplatePipelineJson(source);
1801
+ library[name_1] = source;
1802
+ }
1802
1803
  }
1803
1804
  }
1804
1805
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
@@ -1968,7 +1969,6 @@
1968
1969
  exports.ExecutionTypes = ExecutionTypes;
1969
1970
  exports.MockedEchoNaturalExecutionTools = MockedEchoNaturalExecutionTools;
1970
1971
  exports.PTBK_VERSION = PTBK_VERSION;
1971
- exports.PromptTemplatePipeline = PromptTemplatePipeline;
1972
1972
  exports.PromptTemplatePipelineLibrary = PromptTemplatePipelineLibrary;
1973
1973
  exports.SimplePromptInterfaceTools = SimplePromptInterfaceTools;
1974
1974
  exports.createPtpExecutor = createPtpExecutor;