@promptbook/core 0.28.0-7 → 0.28.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 (23) hide show
  1. package/esm/index.es.js +111 -22
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/conversion/promptTemplatePipelineStringToJson-syntaxErrors.test.d.ts +1 -0
  4. package/esm/typings/conversion/promptTemplatePipelineStringToJson.test.d.ts +0 -3
  5. package/esm/typings/conversion/validatePromptTemplatePipelineJson-logicErrors.test.d.ts +1 -0
  6. package/esm/typings/conversion/validatePromptTemplatePipelineJson.test.d.ts +0 -3
  7. package/esm/typings/execution/UserInterfaceTools.d.ts +16 -1
  8. package/esm/typings/execution/plugins/natural-execution-tools/mocked/joker.test.d.ts +4 -0
  9. package/esm/typings/types/Command.d.ts +8 -1
  10. package/esm/typings/types/PromptTemplatePipelineJson/PromptTemplateJson.d.ts +4 -0
  11. package/esm/typings/types/execution-report/executionReportJsonToString.test.d.ts +0 -3
  12. package/package.json +1 -1
  13. package/umd/index.umd.js +111 -22
  14. package/umd/index.umd.js.map +1 -1
  15. package/umd/typings/conversion/promptTemplatePipelineStringToJson-syntaxErrors.test.d.ts +1 -0
  16. package/umd/typings/conversion/promptTemplatePipelineStringToJson.test.d.ts +0 -3
  17. package/umd/typings/conversion/validatePromptTemplatePipelineJson-logicErrors.test.d.ts +1 -0
  18. package/umd/typings/conversion/validatePromptTemplatePipelineJson.test.d.ts +0 -3
  19. package/umd/typings/execution/UserInterfaceTools.d.ts +16 -1
  20. package/umd/typings/execution/plugins/natural-execution-tools/mocked/joker.test.d.ts +4 -0
  21. package/umd/typings/types/Command.d.ts +8 -1
  22. package/umd/typings/types/PromptTemplatePipelineJson/PromptTemplateJson.d.ts +4 -0
  23. package/umd/typings/types/execution-report/executionReportJsonToString.test.d.ts +0 -3
@@ -1,3 +1,4 @@
1
+ import { number_integer, number_positive } from '../types/typeAliases';
1
2
  /**
2
3
  * Represents all the tools needed to interact with the user.
3
4
  *
@@ -13,12 +14,20 @@ export interface UserInterfaceTools {
13
14
  promptDialog(options: UserInterfaceToolsPromptDialogOptions): Promise<string>;
14
15
  }
15
16
  export interface UserInterfaceToolsPromptDialogOptions {
17
+ /**
18
+ * Prompt title
19
+ *
20
+ * Note: This is not a prompt to language model but a prompt to the user
21
+ * @example "Your name"
22
+ */
23
+ promptTitle: string;
16
24
  /**
17
25
  * Prompt message
18
26
  *
19
27
  * Note: This is not a prompt to language model but a prompt to the user
28
+ * @example "Please enter your name, including your last name, title, etc."
20
29
  */
21
- prompt: string;
30
+ promptMessage: string;
22
31
  /**
23
32
  * Default value for the input/textarea
24
33
  */
@@ -27,4 +36,10 @@ export interface UserInterfaceToolsPromptDialogOptions {
27
36
  * Placeholder for the input/textarea
28
37
  */
29
38
  placeholder?: string;
39
+ /**
40
+ * Priority of the prompt
41
+ *
42
+ * Note: This would be reflected for example into the UI z-index of the prompt modal
43
+ */
44
+ priority: number_integer & number_positive;
30
45
  }
@@ -0,0 +1,4 @@
1
+ export {};
2
+ /**
3
+ * TODO: [🧠] What should be name of this test "MockedEchoExecutionTools.test.ts" or "createPtpExecutor.test.ts"
4
+ */
@@ -6,7 +6,7 @@ import type { ExpectationAmount, ExpectationUnit } from './PromptTemplatePipelin
6
6
  * Command is one piece of the prompt template which adds some logic to the prompt template or the whole pipeline.
7
7
  * It is parsed from the markdown from ul/ol items - one command per one item.
8
8
  */
9
- export type Command = PtbkUrlCommand | PtbkVersionCommand | ExecuteCommand | ModelCommand | ParameterCommand | PostprocessCommand | ExpectCommand;
9
+ export type Command = PtbkUrlCommand | PtbkVersionCommand | ExecuteCommand | ModelCommand | JokerCommand | ParameterCommand | PostprocessCommand | ExpectCommand;
10
10
  /**
11
11
  * PtpVersion command tells which version is .ptp file using
12
12
  *
@@ -43,6 +43,13 @@ export interface ModelCommand {
43
43
  readonly key: keyof ModelRequirements;
44
44
  readonly value: any;
45
45
  }
46
+ /**
47
+ * Joker parameter is used instead of executing the prompt template if it meet the expectations requirements
48
+ */
49
+ export interface JokerCommand {
50
+ readonly type: 'JOKER';
51
+ readonly parameterName: string_name;
52
+ }
46
53
  /**
47
54
  * Parameter command describes one parameter of the prompt template
48
55
  *
@@ -75,6 +75,10 @@ interface PromptTemplateJsonCommon {
75
75
  * It can use multiple paragraphs of simple markdown formatting like **bold**, *italic*, [link](https://example.com), ... BUT not code blocks and structure
76
76
  */
77
77
  readonly description?: string;
78
+ /**
79
+ * If theese parameters meet the expectations requirements, they are used instead of executing this prompt template
80
+ */
81
+ readonly jokers?: Array<string>;
78
82
  /**
79
83
  * Type of the execution
80
84
  * This determines if the prompt template is send to LLM, user or some scripting evaluation
@@ -1,4 +1 @@
1
1
  export {};
2
- /**
3
- * TODO: [💥] Some system to automatically generate tests for all the templates in the folder
4
- */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptbook/core",
3
- "version": "0.28.0-7",
3
+ "version": "0.28.0",
4
4
  "description": "Library to supercharge your use of large language models",
5
5
  "private": false,
6
6
  "sideEffects": false,
package/umd/index.umd.js CHANGED
@@ -574,6 +574,21 @@
574
574
  isInputParameter: isInputParameter,
575
575
  };
576
576
  }
577
+ else if (type.startsWith('JOKER')) {
578
+ if (listItemParts.length !== 2) {
579
+ throw new Error(spaceTrim__default["default"]("\n Invalid JOKER command:\n\n - ".concat(listItem, "\n ")));
580
+ }
581
+ var parametersMatch = (listItemParts.pop() || '').match(/^\{(?<parameterName>[a-z0-9_]+)\}$/im);
582
+ if (!parametersMatch || !parametersMatch.groups || !parametersMatch.groups.parameterName) {
583
+ throw new Error(spaceTrim__default["default"]("\n Invalid parameter in command:\n\n - ".concat(listItem, "\n ")));
584
+ }
585
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
586
+ var parameterName = parametersMatch.groups.parameterName;
587
+ return {
588
+ type: 'JOKER',
589
+ parameterName: parameterName,
590
+ };
591
+ }
577
592
  else if (type.startsWith('POSTPROCESS') || type.startsWith('POST_PROCESS')) {
578
593
  if (listItemParts.length !== 2) {
579
594
  throw new Error(spaceTrim__default["default"]("\n Invalid POSTPROCESSING command:\n\n - ".concat(listItem, "\n ")));
@@ -765,6 +780,7 @@
765
780
  var templateModelRequirements = __assign({}, defaultModelRequirements);
766
781
  var listItems_3 = extractAllListItemsFromMarkdown(section.content);
767
782
  var executionType = 'PROMPT_TEMPLATE';
783
+ var jokers = [];
768
784
  var postprocessing = [];
769
785
  var expectAmount = {};
770
786
  var expectFormat = undefined;
@@ -774,6 +790,9 @@
774
790
  var listItem = listItems_2_1.value;
775
791
  var command = parseCommand(listItem);
776
792
  switch (command.type) {
793
+ case 'JOKER':
794
+ jokers.push(command.parameterName);
795
+ break;
777
796
  case 'EXECUTE':
778
797
  if (isExecutionTypeChanged) {
779
798
  throw new Error('Execution type is already defined in the prompt template. It can be defined only once.');
@@ -856,6 +875,9 @@
856
875
  if (description_1 === '') {
857
876
  description_1 = undefined;
858
877
  }
878
+ if (Object.keys(jokers).length === 0) {
879
+ jokers = undefined;
880
+ }
859
881
  if (Object.keys(expectAmount).length === 0) {
860
882
  expectAmount = undefined;
861
883
  }
@@ -867,6 +889,7 @@
867
889
  title: section.title,
868
890
  description: description_1,
869
891
  executionType: executionType,
892
+ jokers: jokers,
870
893
  postprocessing: postprocessing,
871
894
  expectAmount: expectAmount,
872
895
  expectFormat: expectFormat,
@@ -912,7 +935,7 @@
912
935
  * @throws {Error} if invalid
913
936
  */
914
937
  function validatePromptTemplatePipelineJson(ptp) {
915
- var e_1, _a, e_2, _b;
938
+ var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
916
939
  var definedParameters = new Set(ptp.parameters.filter(function (_a) {
917
940
  var isInput = _a.isInput;
918
941
  return isInput;
@@ -921,11 +944,11 @@
921
944
  return name;
922
945
  }));
923
946
  try {
924
- for (var _c = __values(ptp.promptTemplates), _d = _c.next(); !_d.done; _d = _c.next()) {
925
- var template = _d.value;
947
+ for (var _e = __values(ptp.promptTemplates), _f = _e.next(); !_f.done; _f = _e.next()) {
948
+ var template = _f.value;
926
949
  try {
927
- for (var _e = (e_2 = void 0, __values(Array.from(template.content.matchAll(/\{(?<parameterName>[a-z0-9_]+)\}/gi)))), _f = _e.next(); !_f.done; _f = _e.next()) {
928
- var match = _f.value;
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;
929
952
  var parameterName = match.groups.parameterName;
930
953
  if (!definedParameters.has(parameterName)) {
931
954
  throw new Error("Parameter {".concat(parameterName, "} used before defined"));
@@ -935,20 +958,64 @@
935
958
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
936
959
  finally {
937
960
  try {
938
- if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
961
+ if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
939
962
  }
940
963
  finally { if (e_2) throw e_2.error; }
941
964
  }
942
965
  if (definedParameters.has(template.resultingParameterName)) {
943
966
  throw new Error("Parameter {".concat(template.resultingParameterName, "} is defined multiple times"));
944
967
  }
968
+ if (template.jokers && template.jokers.length > 0) {
969
+ 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"));
974
+ }
975
+ }
976
+ }
977
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
978
+ finally {
979
+ try {
980
+ if (_k && !_k.done && (_c = _j.return)) _c.call(_j);
981
+ }
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");
987
+ }
988
+ }
989
+ if (template.expectAmount) {
990
+ 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;
993
+ if (min !== undefined && max !== undefined && min > max) {
994
+ throw new Error("Min expectation (=".concat(min, ") of ").concat(unit, " is higher than max expectation (=").concat(max, ")"));
995
+ }
996
+ if (min !== undefined && min < 0) {
997
+ throw new Error("Min expectation of ".concat(unit, " must be zero or positive"));
998
+ }
999
+ if (max !== undefined && max <= 0) {
1000
+ throw new Error("Max expectation of ".concat(unit, " must be positive"));
1001
+ }
1002
+ }
1003
+ }
1004
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
1005
+ finally {
1006
+ try {
1007
+ if (_m && !_m.done && (_d = _l.return)) _d.call(_l);
1008
+ }
1009
+ finally { if (e_4) throw e_4.error; }
1010
+ }
1011
+ }
945
1012
  definedParameters.add(template.resultingParameterName);
946
1013
  }
947
1014
  }
948
1015
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
949
1016
  finally {
950
1017
  try {
951
- if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
1018
+ if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
952
1019
  }
953
1020
  finally { if (e_1) throw e_1.error; }
954
1021
  }
@@ -1313,7 +1380,7 @@
1313
1380
  var ptp = options.ptp, tools = options.tools, _a = options.settings, settings = _a === void 0 ? {} : _a;
1314
1381
  var _b = settings.maxExecutionAttempts, maxExecutionAttempts = _b === void 0 ? 3 : _b;
1315
1382
  var ptpExecutor = function (inputParameters, onProgress) { return __awaiter(_this, void 0, void 0, function () {
1316
- var parametersToPass, currentTemplate, executionReport, _loop_1, error_1;
1383
+ var parametersToPass, currentTemplate, executionReport, priority, _loop_1, error_1;
1317
1384
  var _a;
1318
1385
  return __generator(this, function (_b) {
1319
1386
  switch (_b.label) {
@@ -1328,15 +1395,17 @@
1328
1395
  description: ptp.description || undefined,
1329
1396
  promptExecutions: [],
1330
1397
  };
1398
+ priority = ptp.promptTemplates.length;
1331
1399
  _b.label = 1;
1332
1400
  case 1:
1333
1401
  _b.trys.push([1, 5, , 6]);
1334
1402
  _loop_1 = function () {
1335
- var resultingParameter, name_1, title, prompt_1, chatThread, completionResult, result, resultString, expectError, scriptExecutionErrors, maxAttempts, attempt, _c, _d, _e, _f, scriptTools, error_2, e_1_1, _g, _h, functionName, _j, _k, scriptTools, error_3, e_2_1, e_3_1, _l, _m, _o, unit, _p, max, min, amount, error_4;
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, _j, _k, scriptTools, error_3, e_2_1, e_3_1, _l, _m, _o, unit, _p, max, min, amount, error_4;
1336
1404
  var e_1, _q, e_3, _r, e_2, _s, e_4, _t, _u;
1337
1405
  return __generator(this, function (_v) {
1338
1406
  switch (_v.label) {
1339
1407
  case 0:
1408
+ priority--;
1340
1409
  resultingParameter = ptp.getResultingParameter(currentTemplate.name);
1341
1410
  name_1 = "ptp-executor-frame-".concat(currentTemplate.name);
1342
1411
  title = removeEmojis(removeMarkdownFormatting(currentTemplate.title));
@@ -1361,16 +1430,30 @@
1361
1430
  resultString = null;
1362
1431
  expectError = null;
1363
1432
  maxAttempts = currentTemplate.executionType === 'PROMPT_DIALOG' ? Infinity : maxExecutionAttempts;
1364
- attempt = 0;
1433
+ jokers = currentTemplate.jokers || [];
1434
+ attempt = -jokers.length;
1365
1435
  _v.label = 3;
1366
1436
  case 3:
1367
1437
  if (!(attempt < maxAttempts)) return [3 /*break*/, 48];
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
+ }
1368
1444
  result = null;
1369
1445
  resultString = null;
1370
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
+ }
1371
1453
  _v.label = 4;
1372
1454
  case 4:
1373
1455
  _v.trys.push([4, 44, 45, 46]);
1456
+ if (!!isJokerAttempt) return [3 /*break*/, 27];
1374
1457
  _c = currentTemplate.executionType;
1375
1458
  switch (_c) {
1376
1459
  case 'SIMPLE_TEMPLATE': return [3 /*break*/, 5];
@@ -1470,22 +1553,27 @@
1470
1553
  throw scriptExecutionErrors[0];
1471
1554
  }
1472
1555
  else {
1473
- throw new Error(spaceTrim__default["default"](function (block) { return "\n Script execution failed ".concat(scriptExecutionErrors.length, " times\n\n ").concat(block(scriptExecutionErrors.map(function (error) { return '- ' + error.message; }).join('\n\n')), "\n "); }));
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 "); }));
1474
1559
  }
1475
1560
  case 24: return [4 /*yield*/, tools.userInterface.promptDialog({
1476
- prompt: replaceParameters(currentTemplate.description || '', parametersToPass),
1561
+ promptTitle: currentTemplate.title,
1562
+ promptMessage: replaceParameters(currentTemplate.description || '', parametersToPass),
1477
1563
  defaultValue: replaceParameters(currentTemplate.content, parametersToPass),
1478
1564
  // TODO: [🧠] !! Figure out how to define placeholder in .ptbk.md file
1479
1565
  placeholder: undefined,
1566
+ priority: priority /* <- TODO: !!!! Is it ending with 0 */,
1480
1567
  })];
1481
1568
  case 25:
1569
+ // TODO: !!!! When making next attempt for `PROMPT DIALOG`, preserve the previous user input
1482
1570
  resultString = _v.sent();
1483
1571
  return [3 /*break*/, 27];
1484
- case 26:
1572
+ case 26: throw new Error(
1485
1573
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1486
- throw new Error("Unknown execution type \"".concat(currentTemplate.executionType, "\""));
1574
+ "Unknown execution type \"".concat(currentTemplate.executionType, "\""));
1487
1575
  case 27:
1488
- if (!currentTemplate.postprocessing) return [3 /*break*/, 43];
1576
+ if (!(!isJokerAttempt && currentTemplate.postprocessing)) return [3 /*break*/, 43];
1489
1577
  _v.label = 28;
1490
1578
  case 28:
1491
1579
  _v.trys.push([28, 41, 42, 43]);
@@ -1510,7 +1598,7 @@
1510
1598
  return [4 /*yield*/, scriptTools.execute({
1511
1599
  scriptLanguage: "javascript" /* <- TODO: Try it in each languages; In future allow postprocessing with arbitrary combination of languages to combine */,
1512
1600
  script: "".concat(functionName, "(resultString)"),
1513
- parameters: __assign(__assign({}, parametersToPass), { resultString: resultString }),
1601
+ parameters: __assign(__assign({}, parametersToPass), { resultString: resultString || '' }),
1514
1602
  })];
1515
1603
  case 33:
1516
1604
  resultString = _v.sent();
@@ -1553,7 +1641,7 @@
1553
1641
  case 43:
1554
1642
  if (currentTemplate.expectFormat) {
1555
1643
  if (currentTemplate.expectFormat === 'JSON') {
1556
- if (!isValidJsonString(resultString)) {
1644
+ if (!isValidJsonString(resultString || '')) {
1557
1645
  throw new ExpectError('Expected valid JSON string');
1558
1646
  }
1559
1647
  }
@@ -1562,7 +1650,7 @@
1562
1650
  try {
1563
1651
  for (_l = (e_4 = void 0, __values(Object.entries(currentTemplate.expectAmount))), _m = _l.next(); !_m.done; _m = _l.next()) {
1564
1652
  _o = __read(_m.value, 2), unit = _o[0], _p = _o[1], max = _p.max, min = _p.min;
1565
- amount = CountUtils[unit.toUpperCase()](resultString);
1653
+ amount = CountUtils[unit.toUpperCase()](resultString || '');
1566
1654
  if (min && amount < min) {
1567
1655
  throw new ExpectError("Expected at least ".concat(min, " ").concat(unit, " but got ").concat(amount));
1568
1656
  } /* not else */
@@ -1588,7 +1676,8 @@
1588
1676
  expectError = error_4;
1589
1677
  return [3 /*break*/, 46];
1590
1678
  case 45:
1591
- if (currentTemplate.executionType === 'PROMPT_TEMPLATE' &&
1679
+ if (!isJokerAttempt &&
1680
+ currentTemplate.executionType === 'PROMPT_TEMPLATE' &&
1592
1681
  prompt_1
1593
1682
  // <- Note: [2] When some expected parameter is not defined, error will occur in replaceParameters
1594
1683
  // In that case we don’t want to make a report about it because it’s not a natural execution error
@@ -1826,7 +1915,7 @@
1826
1915
  case 1:
1827
1916
  answer = _a.sent();
1828
1917
  if (this.options.isVerbose) {
1829
- console.info(spaceTrim__default["default"](function (block) { return "\n \uD83D\uDCD6 ".concat(block(options.prompt), "\n \uD83D\uDC64 ").concat(block(answer), "\n "); }));
1918
+ console.info(spaceTrim__default["default"](function (block) { return "\n \uD83D\uDCD6 ".concat(block(options.promptTitle), "\n \uD83D\uDC64 ").concat(block(answer), "\n "); }));
1830
1919
  }
1831
1920
  return [2 /*return*/, answer];
1832
1921
  }
@@ -1853,9 +1942,9 @@
1853
1942
  return __awaiter(this, void 0, void 0, function () {
1854
1943
  var answer;
1855
1944
  return __generator(this, function (_a) {
1856
- answer = window.prompt(options.prompt);
1945
+ answer = window.prompt(spaceTrim__default["default"](function (block) { return "\n ".concat(block(options.promptTitle), "\n \n ").concat(block(options.promptMessage), "\n "); }));
1857
1946
  if (this.options.isVerbose) {
1858
- console.info(spaceTrim__default["default"](function (block) { return "\n \uD83D\uDCD6 ".concat(block(options.prompt), "\n \uD83D\uDC64 ").concat(block(answer || '🚫 User cancelled prompt'), "\n "); }));
1947
+ console.info(spaceTrim__default["default"](function (block) { return "\n \uD83D\uDCD6 ".concat(block(options.promptTitle), "\n \uD83D\uDC64 ").concat(block(answer || '🚫 User cancelled prompt'), "\n "); }));
1859
1948
  }
1860
1949
  if (answer === null) {
1861
1950
  throw new Error('User cancelled prompt');