@promptbook/core 0.103.0-42 → 0.103.0-44

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 (92) hide show
  1. package/README.md +6 -18
  2. package/esm/index.es.js +704 -372
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/src/_packages/core.index.d.ts +6 -0
  5. package/esm/typings/src/_packages/node.index.d.ts +0 -2
  6. package/esm/typings/src/_packages/types.index.d.ts +22 -0
  7. package/esm/typings/src/_packages/utils.index.d.ts +2 -0
  8. package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +2 -4
  9. package/esm/typings/src/book-2.0/agent-source/padBook.d.ts +1 -1
  10. package/esm/typings/src/book-2.0/agent-source/string_book.d.ts +1 -0
  11. package/esm/typings/src/book-components/AvatarProfile/AvatarProfile/AvatarProfile.d.ts +6 -1
  12. package/esm/typings/src/book-components/BookEditor/BookEditor.d.ts +1 -1
  13. package/esm/typings/src/book-components/Chat/save/_common/ChatSaveFormatDefinition.d.ts +1 -1
  14. package/esm/typings/src/book-components/Chat/types/ChatParticipant.d.ts +1 -1
  15. package/esm/typings/src/book-components/Qr/BrandedQrCode.d.ts +1 -1
  16. package/esm/typings/src/book-components/Qr/useQrCode.d.ts +1 -1
  17. package/esm/typings/src/cli/cli-commands/_boilerplate.d.ts +1 -1
  18. package/esm/typings/src/cli/cli-commands/about.d.ts +1 -1
  19. package/esm/typings/src/cli/cli-commands/hello.d.ts +1 -1
  20. package/esm/typings/src/cli/cli-commands/list-models.d.ts +1 -1
  21. package/esm/typings/src/cli/cli-commands/list-scrapers.d.ts +1 -1
  22. package/esm/typings/src/cli/cli-commands/login.d.ts +1 -1
  23. package/esm/typings/src/cli/cli-commands/make.d.ts +1 -1
  24. package/esm/typings/src/cli/cli-commands/prettify.d.ts +1 -1
  25. package/esm/typings/src/cli/cli-commands/run.d.ts +1 -1
  26. package/esm/typings/src/cli/cli-commands/start-agents-server.d.ts +1 -1
  27. package/esm/typings/src/cli/cli-commands/start-pipelines-server.d.ts +1 -1
  28. package/esm/typings/src/cli/cli-commands/test-command.d.ts +1 -1
  29. package/esm/typings/src/cli/common/$addGlobalOptionsToCommand.d.ts +1 -1
  30. package/esm/typings/src/collection/agent-collection/AgentCollection.d.ts +2 -29
  31. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +107 -0
  32. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +129 -0
  33. package/esm/typings/src/commands/_common/types/CommandParser.d.ts +1 -1
  34. package/esm/typings/src/config.d.ts +1 -1
  35. package/esm/typings/src/errors/0-index.d.ts +3 -0
  36. package/esm/typings/src/errors/DatabaseError.d.ts +12 -0
  37. package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempts.d.ts +1 -1
  38. package/esm/typings/src/high-level-abstractions/_common/HighLevelAbstraction.d.ts +1 -1
  39. package/esm/typings/src/llm-providers/_common/register/$registeredLlmToolsMessage.d.ts +1 -1
  40. package/esm/typings/src/llm-providers/_common/register/LlmToolsMetadata.d.ts +1 -1
  41. package/esm/typings/src/llm-providers/_multiple/getSingleLlmExecutionTools.d.ts +1 -0
  42. package/esm/typings/src/llm-providers/_multiple/joinLlmExecutionTools.d.ts +1 -0
  43. package/esm/typings/src/llm-providers/agent/Agent.d.ts +5 -2
  44. package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +1 -1
  45. package/esm/typings/src/llm-providers/agent/AgentOptions.d.ts +4 -2
  46. package/esm/typings/src/llm-providers/agent/CreateAgentLlmExecutionToolsOptions.d.ts +4 -3
  47. package/esm/typings/src/llm-providers/agent/createAgentLlmExecutionTools.d.ts +1 -1
  48. package/esm/typings/src/llm-providers/anthropic-claude/anthropic-claude-models.d.ts +1 -1
  49. package/esm/typings/src/llm-providers/google/google-models.d.ts +1 -1
  50. package/esm/typings/src/llm-providers/openai/openai-models.d.ts +1 -1
  51. package/esm/typings/src/prepare/PrepareAndScrapeOptions.d.ts +1 -0
  52. package/esm/typings/src/remote-server/startAgentServer.d.ts +2 -2
  53. package/esm/typings/src/remote-server/types/RemoteServerOptions.d.ts +0 -19
  54. package/esm/typings/src/storage/env-storage/$EnvStorage.d.ts +1 -1
  55. package/esm/typings/src/transpilers/_common/BookTranspiler.d.ts +5 -1
  56. package/esm/typings/src/transpilers/_common/BookTranspilerOptions.d.ts +1 -1
  57. package/esm/typings/src/transpilers/_common/register/$bookTranspilersRegister.d.ts +1 -1
  58. package/esm/typings/src/transpilers/formatted-book-in-markdown/FormattedBookInMarkdownTranspiler.d.ts +4 -1
  59. package/esm/typings/src/transpilers/formatted-book-in-markdown/register.d.ts +1 -1
  60. package/esm/typings/src/transpilers/openai-sdk/OpenAiSdkTranspiler.d.ts +4 -1
  61. package/esm/typings/src/transpilers/openai-sdk/register.d.ts +1 -1
  62. package/esm/typings/src/types/typeAliases.d.ts +19 -1
  63. package/esm/typings/src/utils/color/$randomColor.d.ts +1 -0
  64. package/esm/typings/src/utils/color/operators/darken.d.ts +1 -1
  65. package/esm/typings/src/utils/color/operators/grayscale.d.ts +1 -1
  66. package/esm/typings/src/utils/color/operators/lighten.d.ts +1 -1
  67. package/esm/typings/src/utils/color/operators/mixWithColor.d.ts +1 -1
  68. package/esm/typings/src/utils/color/operators/saturate.d.ts +1 -1
  69. package/esm/typings/src/utils/environment/$detectRuntimeEnvironment.d.ts +16 -0
  70. package/esm/typings/src/utils/execCommand/$execCommand.d.ts +1 -1
  71. package/esm/typings/src/utils/execCommand/$execCommands.d.ts +1 -1
  72. package/esm/typings/src/utils/files/$induceBookDownload.d.ts +2 -2
  73. package/esm/typings/src/utils/files/$induceFileDownload.d.ts +2 -2
  74. package/esm/typings/src/utils/files/ObjectUrl.d.ts +1 -1
  75. package/esm/typings/src/utils/misc/aboutPromptbookInformation.d.ts +6 -0
  76. package/esm/typings/src/utils/organization/$side_effect.d.ts +1 -1
  77. package/esm/typings/src/utils/random/$generateBookBoilerplate.d.ts +25 -0
  78. package/esm/typings/src/utils/random/$randomAgentPersona.d.ts +9 -0
  79. package/esm/typings/src/utils/random/$randomFullnameWithColor.d.ts +13 -0
  80. package/esm/typings/src/utils/random/$randomItem.d.ts +9 -0
  81. package/esm/typings/src/utils/random/$randomSeed.d.ts +3 -0
  82. package/esm/typings/src/utils/random/$randomToken.d.ts +2 -0
  83. package/esm/typings/src/utils/serialization/$deepFreeze.d.ts +1 -1
  84. package/esm/typings/src/utils/serialization/serializeToPromptbookJavascript.d.ts +2 -2
  85. package/esm/typings/src/version.d.ts +1 -1
  86. package/package.json +1 -1
  87. package/umd/index.umd.js +627 -292
  88. package/umd/index.umd.js.map +1 -1
  89. package/esm/typings/src/collection/agent-collection/constructors/AgentCollectionInDirectory.d.ts +0 -89
  90. package/esm/typings/src/collection/agent-collection/constructors/AgentCollectionInDirectory.test.d.ts +0 -1
  91. package/esm/typings/src/commands/_common/parseCommand.test.d.ts +0 -1
  92. package/esm/typings/src/execution/utils/logLlmCall.d.ts +0 -8
package/umd/index.umd.js CHANGED
@@ -1,12 +1,12 @@
1
1
  (function (global, factory) {
2
2
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('spacetrim'), require('crypto'), require('rxjs'), require('waitasecond'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('path'), require('crypto-js'), require('mime-types'), require('papaparse'), require('moment'), require('colors'), require('bottleneck'), require('openai')) :
3
3
  typeof define === 'function' && define.amd ? define(['exports', 'spacetrim', 'crypto', 'rxjs', 'waitasecond', 'crypto-js/enc-hex', 'crypto-js/sha256', 'path', 'crypto-js', 'mime-types', 'papaparse', 'moment', 'colors', 'bottleneck', 'openai'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-core"] = {}, global.spaceTrim, global.crypto, global.rxjs, global.waitasecond, global.hexEncoder, global.sha256, global.path, global.cryptoJs, global.mimeTypes, global.papaparse, global.moment, global.colors, global.Bottleneck, global.OpenAI));
5
- })(this, (function (exports, spaceTrim, crypto, rxjs, waitasecond, hexEncoder, sha256, path, cryptoJs, mimeTypes, papaparse, moment, colors, Bottleneck, OpenAI) { 'use strict';
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-core"] = {}, global.spaceTrim$1, global.crypto, global.rxjs, global.waitasecond, global.hexEncoder, global.sha256, global.path, global.cryptoJs, global.mimeTypes, global.papaparse, global.moment, global.colors, global.Bottleneck, global.OpenAI));
5
+ })(this, (function (exports, spaceTrim$1, crypto, rxjs, waitasecond, hexEncoder, sha256, path, cryptoJs, mimeTypes, papaparse, moment, colors, Bottleneck, OpenAI) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
9
- var spaceTrim__default = /*#__PURE__*/_interopDefaultLegacy(spaceTrim);
9
+ var spaceTrim__default = /*#__PURE__*/_interopDefaultLegacy(spaceTrim$1);
10
10
  var hexEncoder__default = /*#__PURE__*/_interopDefaultLegacy(hexEncoder);
11
11
  var sha256__default = /*#__PURE__*/_interopDefaultLegacy(sha256);
12
12
  var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
@@ -21,14 +21,14 @@
21
21
  * @generated
22
22
  * @see https://github.com/webgptorg/book
23
23
  */
24
- const BOOK_LANGUAGE_VERSION = '1.0.0';
24
+ const BOOK_LANGUAGE_VERSION = '2.0.0';
25
25
  /**
26
26
  * The version of the Promptbook engine
27
27
  *
28
28
  * @generated
29
29
  * @see https://github.com/webgptorg/promptbook
30
30
  */
31
- const PROMPTBOOK_ENGINE_VERSION = '0.103.0-42';
31
+ const PROMPTBOOK_ENGINE_VERSION = '0.103.0-44';
32
32
  /**
33
33
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
34
34
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -842,6 +842,23 @@
842
842
  * TODO: Maybe connect with textures
843
843
  */
844
844
 
845
+ /**
846
+ * Makes color transformer which returns a grayscale version of the color
847
+ *
848
+ * @param amount from 0 to 1
849
+ *
850
+ * @public exported from `@promptbook/color`
851
+ */
852
+ function grayscale(amount) {
853
+ return ({ red, green, blue, alpha }) => {
854
+ const average = (red + green + blue) / 3;
855
+ red = Math.round(average * amount + red * (1 - amount));
856
+ green = Math.round(average * amount + green * (1 - amount));
857
+ blue = Math.round(average * amount + blue * (1 - amount));
858
+ return Color.fromValues(red, green, blue, alpha);
859
+ };
860
+ }
861
+
845
862
  /**
846
863
  * Converts HSL values to RGB values
847
864
  *
@@ -957,102 +974,6 @@
957
974
  * TODO: Maybe implement by mix+hsl
958
975
  */
959
976
 
960
- /**
961
- * Calculates distance between two colors
962
- *
963
- * @param color1 first color
964
- * @param color2 second color
965
- *
966
- * Note: This function is inefficient. Use colorDistanceSquared instead if possible.
967
- *
968
- * @public exported from `@promptbook/color`
969
- */
970
- /**
971
- * Calculates distance between two colors without square root
972
- *
973
- * @param color1 first color
974
- * @param color2 second color
975
- *
976
- * @public exported from `@promptbook/color`
977
- */
978
- function colorDistanceSquared(color1, color2) {
979
- const rmean = (color1.red + color2.red) / 2;
980
- const r = color1.red - color2.red;
981
- const g = color1.green - color2.green;
982
- const b = color1.blue - color2.blue;
983
- const weightR = 2 + rmean / 256;
984
- const weightG = 4.0;
985
- const weightB = 2 + (255 - rmean) / 256;
986
- const distance = weightR * r * r + weightG * g * g + weightB * b * b;
987
- return distance;
988
- }
989
-
990
- /**
991
- * Makes color transformer which finds the nearest color from the given list
992
- *
993
- * @param colors array of colors to choose from
994
- *
995
- * @public exported from `@promptbook/color`
996
- */
997
- function nearest(...colors) {
998
- return (color) => {
999
- const distances = colors.map((c) => colorDistanceSquared(c, color));
1000
- const minDistance = Math.min(...distances);
1001
- const minIndex = distances.indexOf(minDistance);
1002
- const nearestColor = colors[minIndex];
1003
- return nearestColor;
1004
- };
1005
- }
1006
-
1007
- /**
1008
- * Color transformer which returns the negative color
1009
- *
1010
- * @public exported from `@promptbook/color`
1011
- */
1012
- function negative(color) {
1013
- const r = 255 - color.red;
1014
- const g = 255 - color.green;
1015
- const b = 255 - color.blue;
1016
- return Color.fromValues(r, g, b, color.alpha);
1017
- }
1018
-
1019
- /**
1020
- * Makes color transformer which finds the furthest color from the given list
1021
- *
1022
- * @param colors array of colors to choose from
1023
- *
1024
- * @public exported from `@promptbook/color`
1025
- */
1026
- function furthest(...colors) {
1027
- return (color) => {
1028
- const furthestColor = negative(nearest(...colors.map(negative))(color));
1029
- return furthestColor;
1030
- };
1031
- }
1032
- /**
1033
- * Makes color transformer which finds the best text color (black or white) for the given background color
1034
- *
1035
- * @public exported from `@promptbook/color`
1036
- */
1037
- furthest(Color.get('white'), Color.from('black'));
1038
-
1039
- /**
1040
- * Makes color transformer which returns a grayscale version of the color
1041
- *
1042
- * @param amount from 0 to 1
1043
- *
1044
- * @public exported from `@promptbook/color`
1045
- */
1046
- function grayscale(amount) {
1047
- return ({ red, green, blue, alpha }) => {
1048
- const average = (red + green + blue) / 3;
1049
- red = Math.round(average * amount + red * (1 - amount));
1050
- green = Math.round(average * amount + green * (1 - amount));
1051
- blue = Math.round(average * amount + blue * (1 - amount));
1052
- return Color.fromValues(red, green, blue, alpha);
1053
- };
1054
- }
1055
-
1056
977
  /**
1057
978
  * Makes color transformer which saturate the given color
1058
979
  *
@@ -1462,6 +1383,19 @@
1462
1383
  /**/
1463
1384
  // Note: In normal situations, we check the pipeline logic:
1464
1385
  true);
1386
+ /**
1387
+ * Indicates whether cost-prevention is enabled. When true, real API keys are prevented from being used in tests.
1388
+ *
1389
+ * @private within the repository
1390
+ */
1391
+ const IS_COST_PREVENTED = just(
1392
+ /*/
1393
+ // Note: In normal situations, we prevent ability to use real API keys in tests:
1394
+ true,
1395
+ /**/
1396
+ /**/
1397
+ // When working on preparations, you can temporarily turn off the prevention:
1398
+ false);
1465
1399
  /**
1466
1400
  * Note: [💞] Ignore a discrepancy between file name and entity name
1467
1401
  * TODO: [🧠][🧜‍♂️] Maybe join remoteServerUrl and path into single value
@@ -1518,7 +1452,7 @@
1518
1452
  */
1519
1453
  class UnexpectedError extends Error {
1520
1454
  constructor(message) {
1521
- super(spaceTrim.spaceTrim((block) => `
1455
+ super(spaceTrim$1.spaceTrim((block) => `
1522
1456
  ${block(message)}
1523
1457
 
1524
1458
  Note: This error should not happen.
@@ -1544,7 +1478,7 @@
1544
1478
  constructor(whatWasThrown) {
1545
1479
  const tag = `[🤮]`;
1546
1480
  console.error(tag, whatWasThrown);
1547
- super(spaceTrim.spaceTrim(`
1481
+ super(spaceTrim$1.spaceTrim(`
1548
1482
  Non-Error object was thrown
1549
1483
 
1550
1484
  Note: Look for ${tag} in the console for more details
@@ -2257,7 +2191,7 @@
2257
2191
  if (!(error instanceof PipelineLogicError)) {
2258
2192
  throw error;
2259
2193
  }
2260
- console.error(spaceTrim.spaceTrim((block) => `
2194
+ console.error(spaceTrim$1.spaceTrim((block) => `
2261
2195
  Pipeline is not valid but logic errors are temporarily disabled via \`IS_PIPELINE_LOGIC_VALIDATED\`
2262
2196
 
2263
2197
  ${block(error.message)}
@@ -2284,7 +2218,7 @@
2284
2218
  })();
2285
2219
  if (pipeline.pipelineUrl !== undefined && !isValidPipelineUrl(pipeline.pipelineUrl)) {
2286
2220
  // <- Note: [🚲]
2287
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
2221
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
2288
2222
  Invalid promptbook URL "${pipeline.pipelineUrl}"
2289
2223
 
2290
2224
  ${block(pipelineIdentification)}
@@ -2292,7 +2226,7 @@
2292
2226
  }
2293
2227
  if (pipeline.bookVersion !== undefined && !isValidPromptbookVersion(pipeline.bookVersion)) {
2294
2228
  // <- Note: [🚲]
2295
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
2229
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
2296
2230
  Invalid Promptbook Version "${pipeline.bookVersion}"
2297
2231
 
2298
2232
  ${block(pipelineIdentification)}
@@ -2301,7 +2235,7 @@
2301
2235
  // TODO: [🧠] Maybe do here some proper JSON-schema / ZOD checking
2302
2236
  if (!Array.isArray(pipeline.parameters)) {
2303
2237
  // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
2304
- throw new ParseError(spaceTrim.spaceTrim((block) => `
2238
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
2305
2239
  Pipeline is valid JSON but with wrong structure
2306
2240
 
2307
2241
  \`PipelineJson.parameters\` expected to be an array, but got ${typeof pipeline.parameters}
@@ -2312,7 +2246,7 @@
2312
2246
  // TODO: [🧠] Maybe do here some proper JSON-schema / ZOD checking
2313
2247
  if (!Array.isArray(pipeline.tasks)) {
2314
2248
  // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
2315
- throw new ParseError(spaceTrim.spaceTrim((block) => `
2249
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
2316
2250
  Pipeline is valid JSON but with wrong structure
2317
2251
 
2318
2252
  \`PipelineJson.tasks\` expected to be an array, but got ${typeof pipeline.tasks}
@@ -2338,7 +2272,7 @@
2338
2272
  // Note: Check each parameter individually
2339
2273
  for (const parameter of pipeline.parameters) {
2340
2274
  if (parameter.isInput && parameter.isOutput) {
2341
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
2275
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
2342
2276
 
2343
2277
  Parameter \`{${parameter.name}}\` can not be both input and output
2344
2278
 
@@ -2349,7 +2283,7 @@
2349
2283
  if (!parameter.isInput &&
2350
2284
  !parameter.isOutput &&
2351
2285
  !pipeline.tasks.some((task) => task.dependentParameterNames.includes(parameter.name))) {
2352
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
2286
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
2353
2287
  Parameter \`{${parameter.name}}\` is created but not used
2354
2288
 
2355
2289
  You can declare {${parameter.name}} as output parameter by adding in the header:
@@ -2361,7 +2295,7 @@
2361
2295
  }
2362
2296
  // Note: Testing that parameter is either input or result of some task
2363
2297
  if (!parameter.isInput && !pipeline.tasks.some((task) => task.resultingParameterName === parameter.name)) {
2364
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
2298
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
2365
2299
  Parameter \`{${parameter.name}}\` is declared but not defined
2366
2300
 
2367
2301
  You can do one of these:
@@ -2377,14 +2311,14 @@
2377
2311
  // Note: Checking each task individually
2378
2312
  for (const task of pipeline.tasks) {
2379
2313
  if (definedParameters.has(task.resultingParameterName)) {
2380
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
2314
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
2381
2315
  Parameter \`{${task.resultingParameterName}}\` is defined multiple times
2382
2316
 
2383
2317
  ${block(pipelineIdentification)}
2384
2318
  `));
2385
2319
  }
2386
2320
  if (RESERVED_PARAMETER_NAMES.includes(task.resultingParameterName)) {
2387
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
2321
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
2388
2322
  Parameter name {${task.resultingParameterName}} is reserved, please use different name
2389
2323
 
2390
2324
  ${block(pipelineIdentification)}
@@ -2394,7 +2328,7 @@
2394
2328
  if (task.jokerParameterNames && task.jokerParameterNames.length > 0) {
2395
2329
  if (!task.format &&
2396
2330
  !task.expectations /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
2397
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
2331
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
2398
2332
  Joker parameters are used for {${task.resultingParameterName}} but no expectations are defined
2399
2333
 
2400
2334
  ${block(pipelineIdentification)}
@@ -2402,7 +2336,7 @@
2402
2336
  }
2403
2337
  for (const joker of task.jokerParameterNames) {
2404
2338
  if (!task.dependentParameterNames.includes(joker)) {
2405
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
2339
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
2406
2340
  Parameter \`{${joker}}\` is used for {${task.resultingParameterName}} as joker but not in \`dependentParameterNames\`
2407
2341
 
2408
2342
  ${block(pipelineIdentification)}
@@ -2413,21 +2347,21 @@
2413
2347
  if (task.expectations) {
2414
2348
  for (const [unit, { min, max }] of Object.entries(task.expectations)) {
2415
2349
  if (min !== undefined && max !== undefined && min > max) {
2416
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
2350
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
2417
2351
  Min expectation (=${min}) of ${unit} is higher than max expectation (=${max})
2418
2352
 
2419
2353
  ${block(pipelineIdentification)}
2420
2354
  `));
2421
2355
  }
2422
2356
  if (min !== undefined && min < 0) {
2423
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
2357
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
2424
2358
  Min expectation of ${unit} must be zero or positive
2425
2359
 
2426
2360
  ${block(pipelineIdentification)}
2427
2361
  `));
2428
2362
  }
2429
2363
  if (max !== undefined && max <= 0) {
2430
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
2364
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
2431
2365
  Max expectation of ${unit} must be positive
2432
2366
 
2433
2367
  ${block(pipelineIdentification)}
@@ -2449,7 +2383,7 @@
2449
2383
  while (unresovedTasks.length > 0) {
2450
2384
  if (loopLimit-- < 0) {
2451
2385
  // Note: Really UnexpectedError not LimitReachedError - this should not happen and be caught below
2452
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
2386
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
2453
2387
  Loop limit reached during detection of circular dependencies in \`validatePipeline\`
2454
2388
 
2455
2389
  ${block(pipelineIdentification)}
@@ -2459,7 +2393,7 @@
2459
2393
  if (currentlyResovedTasks.length === 0) {
2460
2394
  throw new PipelineLogicError(
2461
2395
  // TODO: [🐎] DRY
2462
- spaceTrim.spaceTrim((block) => `
2396
+ spaceTrim$1.spaceTrim((block) => `
2463
2397
 
2464
2398
  Can not resolve some parameters:
2465
2399
  Either you are using a parameter that is not defined, or there are some circular dependencies.
@@ -2623,7 +2557,7 @@
2623
2557
  for (const pipeline of pipelines) {
2624
2558
  // TODO: [👠] DRY
2625
2559
  if (pipeline.pipelineUrl === undefined) {
2626
- throw new PipelineUrlError(spaceTrim.spaceTrim(`
2560
+ throw new PipelineUrlError(spaceTrim$1.spaceTrim(`
2627
2561
  Pipeline with name "${pipeline.title}" does not have defined URL
2628
2562
 
2629
2563
  File:
@@ -2645,7 +2579,7 @@
2645
2579
  pipelineJsonToString(unpreparePipeline(pipeline)) !==
2646
2580
  pipelineJsonToString(unpreparePipeline(this.collection.get(pipeline.pipelineUrl)))) {
2647
2581
  const existing = this.collection.get(pipeline.pipelineUrl);
2648
- throw new PipelineUrlError(spaceTrim.spaceTrim(`
2582
+ throw new PipelineUrlError(spaceTrim$1.spaceTrim(`
2649
2583
  Pipeline with URL ${pipeline.pipelineUrl} is already in the collection 🍎
2650
2584
 
2651
2585
  Conflicting files:
@@ -2677,13 +2611,13 @@
2677
2611
  const pipeline = this.collection.get(url);
2678
2612
  if (!pipeline) {
2679
2613
  if (this.listPipelines().length === 0) {
2680
- throw new NotFoundError(spaceTrim.spaceTrim(`
2614
+ throw new NotFoundError(spaceTrim$1.spaceTrim(`
2681
2615
  Pipeline with url "${url}" not found
2682
2616
 
2683
2617
  No pipelines available
2684
2618
  `));
2685
2619
  }
2686
- throw new NotFoundError(spaceTrim.spaceTrim((block) => `
2620
+ throw new NotFoundError(spaceTrim$1.spaceTrim((block) => `
2687
2621
  Pipeline with url "${url}" not found
2688
2622
 
2689
2623
  Available pipelines:
@@ -2724,7 +2658,7 @@
2724
2658
  */
2725
2659
  class MissingToolsError extends Error {
2726
2660
  constructor(message) {
2727
- super(spaceTrim.spaceTrim((block) => `
2661
+ super(spaceTrim$1.spaceTrim((block) => `
2728
2662
  ${block(message)}
2729
2663
 
2730
2664
  Note: You have probably forgot to provide some tools for pipeline execution or preparation
@@ -2831,6 +2765,22 @@
2831
2765
  }
2832
2766
  }
2833
2767
 
2768
+ /**
2769
+ * This error indicates error from the database
2770
+ *
2771
+ * @public exported from `@promptbook/core`
2772
+ */
2773
+ class DatabaseError extends Error {
2774
+ constructor(message) {
2775
+ super(message);
2776
+ this.name = 'DatabaseError';
2777
+ Object.setPrototypeOf(this, DatabaseError.prototype);
2778
+ }
2779
+ }
2780
+ /**
2781
+ * TODO: !!!! Explain that NotFoundError (!!! and other specific errors) has priority over DatabaseError in some contexts
2782
+ */
2783
+
2834
2784
  /**
2835
2785
  * This error type indicates that you try to use a feature that is not available in the current environment
2836
2786
  *
@@ -2906,7 +2856,7 @@
2906
2856
  */
2907
2857
  class NotYetImplementedError extends Error {
2908
2858
  constructor(message) {
2909
- super(spaceTrim.spaceTrim((block) => `
2859
+ super(spaceTrim$1.spaceTrim((block) => `
2910
2860
  ${block(message)}
2911
2861
 
2912
2862
  Note: This feature is not implemented yet but it will be soon.
@@ -2925,6 +2875,7 @@
2925
2875
  /**
2926
2876
  * Generates random token
2927
2877
  *
2878
+ * Note: `$` is used to indicate that this function is not a pure function - it is not deterministic
2928
2879
  * Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
2929
2880
  *
2930
2881
  * @private internal helper function
@@ -2934,6 +2885,7 @@
2934
2885
  return crypto.randomBytes(randomness).toString('hex');
2935
2886
  }
2936
2887
  /**
2888
+ * TODO: [🤶] Maybe export through `@promptbook/utils` or `@promptbook/random` package
2937
2889
  * TODO: Maybe use nanoid instead https://github.com/ai/nanoid
2938
2890
  */
2939
2891
 
@@ -2994,6 +2946,7 @@
2994
2946
  UnexpectedError,
2995
2947
  WrappedError,
2996
2948
  NotAllowed,
2949
+ DatabaseError,
2997
2950
  // TODO: [🪑]> VersionMismatchError,
2998
2951
  };
2999
2952
  /**
@@ -3178,11 +3131,11 @@
3178
3131
  throw deserializeError(errors[0]);
3179
3132
  }
3180
3133
  else {
3181
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
3134
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
3182
3135
  Multiple errors occurred during Promptbook execution
3183
3136
 
3184
3137
  ${block(errors
3185
- .map(({ name, stack, message }, index) => spaceTrim.spaceTrim((block) => `
3138
+ .map(({ name, stack, message }, index) => spaceTrim$1.spaceTrim((block) => `
3186
3139
  ${name} ${index + 1}:
3187
3140
  ${block(stack || message)}
3188
3141
  `))
@@ -3830,6 +3783,7 @@
3830
3783
  return new MultipleLlmExecutionTools(title || 'Multiple LLM Providers joined by `joinLlmExecutionTools`', ...llmExecutionTools);
3831
3784
  }
3832
3785
  /**
3786
+ * TODO: [🙆] `getSingleLlmExecutionTools` vs `joinLlmExecutionTools` - explain difference or pick one
3833
3787
  * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
3834
3788
  */
3835
3789
 
@@ -3846,6 +3800,7 @@
3846
3800
  return llmTools;
3847
3801
  }
3848
3802
  /**
3803
+ * TODO: [🙆] `getSingleLlmExecutionTools` vs `joinLlmExecutionTools` - explain difference or pick one
3849
3804
  * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
3850
3805
  */
3851
3806
 
@@ -4908,7 +4863,7 @@
4908
4863
  if (task.taskType === 'PROMPT_TASK' &&
4909
4864
  knowledgePiecesCount > 0 &&
4910
4865
  !dependentParameterNames.includes('knowledge')) {
4911
- preparedContent = spaceTrim.spaceTrim(`
4866
+ preparedContent = spaceTrim$1.spaceTrim(`
4912
4867
  {content}
4913
4868
 
4914
4869
  ## Knowledge
@@ -5221,7 +5176,7 @@
5221
5176
  }
5222
5177
  catch (error) {
5223
5178
  assertsError(error);
5224
- throw new ParseError(spaceTrim.spaceTrim((block) => `
5179
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
5225
5180
  Can not extract variables from the script
5226
5181
  ${block(error.stack || error.message)}
5227
5182
 
@@ -5777,18 +5732,6 @@
5777
5732
  return replacedTemplates;
5778
5733
  }
5779
5734
 
5780
- /**
5781
- * Logs an LLM call with the given report.
5782
- *
5783
- * @private internal utility of `createPipelineExecutor`
5784
- */
5785
- function logLlmCall(logLlmCall, report) {
5786
- logLlmCall({
5787
- modelName: 'model' /* <- TODO: How to get model name from the report */,
5788
- report,
5789
- });
5790
- }
5791
-
5792
5735
  /**
5793
5736
  * Extracts all code blocks from markdown.
5794
5737
  *
@@ -6107,7 +6050,7 @@
6107
6050
  }
6108
6051
  catch (error) {
6109
6052
  keepUnused(error);
6110
- throw new ExpectError(spaceTrim.spaceTrim((block) => `
6053
+ throw new ExpectError(spaceTrim$1.spaceTrim((block) => `
6111
6054
  Expected valid JSON string
6112
6055
 
6113
6056
  The expected JSON text:
@@ -6156,7 +6099,7 @@
6156
6099
  */
6157
6100
  async function executeAttempts(options) {
6158
6101
  const { jokerParameterNames, priority, maxAttempts, // <- Note: [💂]
6159
- preparedContent, parameters, task, preparedPipeline, tools, $executionReport, pipelineIdentification, maxExecutionAttempts, onProgress, logLlmCall: logLlmCall$1, } = options;
6102
+ preparedContent, parameters, task, preparedPipeline, tools, $executionReport, pipelineIdentification, maxExecutionAttempts, onProgress, logLlmCall, } = options;
6160
6103
  const $ongoingTaskResult = {
6161
6104
  $result: null,
6162
6105
  $resultString: null,
@@ -6170,7 +6113,7 @@
6170
6113
  const jokerParameterName = jokerParameterNames[jokerParameterNames.length + attemptIndex];
6171
6114
  // TODO: [🧠][🍭] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
6172
6115
  if (isJokerAttempt && !jokerParameterName) {
6173
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
6116
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
6174
6117
  Joker not found in attempt ${attemptIndex}
6175
6118
 
6176
6119
  ${block(pipelineIdentification)}
@@ -6181,7 +6124,7 @@
6181
6124
  $ongoingTaskResult.$expectError = null;
6182
6125
  if (isJokerAttempt) {
6183
6126
  if (parameters[jokerParameterName] === undefined) {
6184
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
6127
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
6185
6128
  Joker parameter {${jokerParameterName}} not defined
6186
6129
 
6187
6130
  ${block(pipelineIdentification)}
@@ -6239,7 +6182,7 @@
6239
6182
  $ongoingTaskResult.$resultString = $ongoingTaskResult.$completionResult.content;
6240
6183
  break variant;
6241
6184
  case 'EMBEDDING':
6242
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
6185
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
6243
6186
  Embedding model can not be used in pipeline
6244
6187
 
6245
6188
  This should be catched during parsing
@@ -6250,7 +6193,7 @@
6250
6193
  break variant;
6251
6194
  // <- case [🤖]:
6252
6195
  default:
6253
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
6196
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
6254
6197
  Unknown model variant "${task.modelRequirements.modelVariant}"
6255
6198
 
6256
6199
  ${block(pipelineIdentification)}
@@ -6261,14 +6204,14 @@
6261
6204
  break;
6262
6205
  case 'SCRIPT_TASK':
6263
6206
  if (arrayableToArray(tools.script).length === 0) {
6264
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
6207
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
6265
6208
  No script execution tools are available
6266
6209
 
6267
6210
  ${block(pipelineIdentification)}
6268
6211
  `));
6269
6212
  }
6270
6213
  if (!task.contentLanguage) {
6271
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
6214
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
6272
6215
  Script language is not defined for SCRIPT TASK "${task.name}"
6273
6216
 
6274
6217
  ${block(pipelineIdentification)}
@@ -6299,7 +6242,7 @@
6299
6242
  throw $ongoingTaskResult.$scriptPipelineExecutionErrors[0];
6300
6243
  }
6301
6244
  else {
6302
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
6245
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
6303
6246
  Script execution failed ${$ongoingTaskResult.$scriptPipelineExecutionErrors.length}x
6304
6247
 
6305
6248
  ${block(pipelineIdentification)}
@@ -6313,7 +6256,7 @@
6313
6256
  break taskType;
6314
6257
  case 'DIALOG_TASK':
6315
6258
  if (tools.userInterface === undefined) {
6316
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
6259
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
6317
6260
  User interface tools are not available
6318
6261
 
6319
6262
  ${block(pipelineIdentification)}
@@ -6331,7 +6274,7 @@
6331
6274
  break taskType;
6332
6275
  // <- case: [🅱]
6333
6276
  default:
6334
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
6277
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
6335
6278
  Unknown execution type "${task.taskType}"
6336
6279
 
6337
6280
  ${block(pipelineIdentification)}
@@ -6418,15 +6361,18 @@
6418
6361
  : serializeError($ongoingTaskResult.$expectError),
6419
6362
  };
6420
6363
  $executionReport.promptExecutions.push(executionPromptReport);
6421
- if (logLlmCall$1) {
6422
- logLlmCall(logLlmCall$1, executionPromptReport);
6364
+ if (logLlmCall) {
6365
+ logLlmCall({
6366
+ modelName: 'model' /* <- TODO: How to get model name from the report */,
6367
+ report: executionPromptReport,
6368
+ });
6423
6369
  }
6424
6370
  }
6425
6371
  }
6426
6372
  if ($ongoingTaskResult.$expectError !== null && attemptIndex === maxAttempts - 1) {
6427
6373
  // Note: Create a summary of all failures
6428
6374
  const failuresSummary = $ongoingTaskResult.$failedResults
6429
- .map((failure) => spaceTrim.spaceTrim((block) => {
6375
+ .map((failure) => spaceTrim$1.spaceTrim((block) => {
6430
6376
  var _a, _b;
6431
6377
  return `
6432
6378
  Attempt ${failure.attemptIndex + 1}:
@@ -6436,14 +6382,14 @@
6436
6382
  Result:
6437
6383
  ${block(failure.result === null
6438
6384
  ? 'null'
6439
- : spaceTrim.spaceTrim(failure.result)
6385
+ : spaceTrim$1.spaceTrim(failure.result)
6440
6386
  .split('\n')
6441
6387
  .map((line) => `> ${line}`)
6442
6388
  .join('\n'))}
6443
6389
  `;
6444
6390
  }))
6445
6391
  .join('\n\n---\n\n');
6446
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => {
6392
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => {
6447
6393
  var _a;
6448
6394
  return `
6449
6395
  LLM execution failed ${maxExecutionAttempts}x
@@ -6463,7 +6409,7 @@
6463
6409
  }
6464
6410
  }
6465
6411
  if ($ongoingTaskResult.$resultString === null) {
6466
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
6412
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
6467
6413
  Something went wrong and prompt result is null
6468
6414
 
6469
6415
  ${block(pipelineIdentification)}
@@ -6693,7 +6639,7 @@
6693
6639
  },
6694
6640
  content: task.content,
6695
6641
  parameters,
6696
- };
6642
+ }; /* <- Note: [🤛] */
6697
6643
  const taskEmbeddingResult = await llmTools.callEmbeddingModel(taskEmbeddingPrompt);
6698
6644
  const knowledgePiecesWithRelevance = preparedPipeline.knowledgePieces.map((knowledgePiece) => {
6699
6645
  const { index } = knowledgePiece;
@@ -6769,7 +6715,7 @@
6769
6715
  // Note: Doublecheck that ALL reserved parameters are defined:
6770
6716
  for (const parameterName of RESERVED_PARAMETER_NAMES) {
6771
6717
  if (reservedParameters[parameterName] === undefined) {
6772
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
6718
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
6773
6719
  Reserved parameter {${parameterName}} is not defined
6774
6720
 
6775
6721
  ${block(pipelineIdentification)}
@@ -6795,7 +6741,7 @@
6795
6741
  const dependentParameterNames = new Set(currentTask.dependentParameterNames);
6796
6742
  // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
6797
6743
  if (difference(union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)), new Set(RESERVED_PARAMETER_NAMES)).size !== 0) {
6798
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
6744
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
6799
6745
  Dependent parameters are not consistent with used parameters:
6800
6746
 
6801
6747
  Dependent parameters:
@@ -6839,7 +6785,7 @@
6839
6785
  else if (!definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
6840
6786
  // Houston, we have a problem
6841
6787
  // Note: Checking part is also done in `validatePipeline`, but it’s good to doublecheck
6842
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
6788
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
6843
6789
  Parameter \`{${parameterName}}\` is NOT defined
6844
6790
  BUT used in task "${currentTask.title || currentTask.name}"
6845
6791
 
@@ -6908,7 +6854,7 @@
6908
6854
  for (const parameter of preparedPipeline.parameters.filter(({ isOutput }) => isOutput)) {
6909
6855
  if (parametersToPass[parameter.name] === undefined) {
6910
6856
  // [4]
6911
- $warnings.push(new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
6857
+ $warnings.push(new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
6912
6858
  Parameter \`{${parameter.name}}\` should be an output parameter, but it was not generated during pipeline execution
6913
6859
 
6914
6860
  Note: This is a warning which happened after the pipeline was executed, and \`{${parameter.name}}\` was not for some reason defined in output parameters
@@ -7016,7 +6962,7 @@
7016
6962
  for (const parameterName of Object.keys(inputParameters)) {
7017
6963
  const parameter = preparedPipeline.parameters.find(({ name }) => name === parameterName);
7018
6964
  if (parameter === undefined) {
7019
- warnings.push(new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
6965
+ warnings.push(new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
7020
6966
  Extra parameter {${parameterName}} is being passed which is not part of the pipeline.
7021
6967
 
7022
6968
  ${block(pipelineIdentification)}
@@ -7031,7 +6977,7 @@
7031
6977
  // TODO: [🧠] This should be also non-critical error
7032
6978
  return exportJson({
7033
6979
  name: 'pipelineExecutorResult',
7034
- message: spaceTrim.spaceTrim((block) => `
6980
+ message: spaceTrim$1.spaceTrim((block) => `
7035
6981
  Unsuccessful PipelineExecutorResult (with extra parameter {${parameter.name}}) PipelineExecutorResult
7036
6982
 
7037
6983
  ${block(pipelineIdentification)}
@@ -7040,7 +6986,7 @@
7040
6986
  value: {
7041
6987
  isSuccessful: false,
7042
6988
  errors: [
7043
- new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
6989
+ new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
7044
6990
  Parameter \`{${parameter.name}}\` is passed as input parameter but it is not input
7045
6991
 
7046
6992
  ${block(pipelineIdentification)}
@@ -7067,7 +7013,7 @@
7067
7013
  while (unresovedTasks.length > 0) {
7068
7014
  if (loopLimit-- < 0) {
7069
7015
  // Note: Really UnexpectedError not LimitReachedError - this should be catched during validatePipeline
7070
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
7016
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
7071
7017
  Loop limit reached during resolving parameters pipeline execution
7072
7018
 
7073
7019
  ${block(pipelineIdentification)}
@@ -7077,7 +7023,7 @@
7077
7023
  if (!currentTask && resolving.length === 0) {
7078
7024
  throw new UnexpectedError(
7079
7025
  // TODO: [🐎] DRY
7080
- spaceTrim.spaceTrim((block) => `
7026
+ spaceTrim$1.spaceTrim((block) => `
7081
7027
  Can not resolve some parameters:
7082
7028
 
7083
7029
  ${block(pipelineIdentification)}
@@ -7117,7 +7063,7 @@
7117
7063
  tools,
7118
7064
  onProgress(newOngoingResult) {
7119
7065
  if (isReturned) {
7120
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
7066
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
7121
7067
  Can not call \`onProgress\` after pipeline execution is finished
7122
7068
 
7123
7069
  ${block(pipelineIdentification)}
@@ -7134,7 +7080,7 @@
7134
7080
  },
7135
7081
  logLlmCall,
7136
7082
  $executionReport: executionReport,
7137
- pipelineIdentification: spaceTrim.spaceTrim((block) => `
7083
+ pipelineIdentification: spaceTrim$1.spaceTrim((block) => `
7138
7084
  ${block(pipelineIdentification)}
7139
7085
  Task name: ${currentTask.name}
7140
7086
  Task title: ${currentTask.title}
@@ -7243,7 +7189,7 @@
7243
7189
  preparedPipeline = pipeline;
7244
7190
  }
7245
7191
  else if (isNotPreparedWarningSuppressed !== true) {
7246
- console.warn(spaceTrim.spaceTrim((block) => `
7192
+ console.warn(spaceTrim$1.spaceTrim((block) => `
7247
7193
  Pipeline is not prepared
7248
7194
 
7249
7195
  ${block(pipelineIdentification)}
@@ -7268,7 +7214,7 @@
7268
7214
  tools,
7269
7215
  onProgress,
7270
7216
  logLlmCall,
7271
- pipelineIdentification: spaceTrim.spaceTrim((block) => `
7217
+ pipelineIdentification: spaceTrim$1.spaceTrim((block) => `
7272
7218
  ${block(pipelineIdentification)}
7273
7219
  ${runCount === 1 ? '' : `Run #${runCount}`}
7274
7220
  `),
@@ -7599,7 +7545,7 @@
7599
7545
  * Markdown documentation for ACTION commitment.
7600
7546
  */
7601
7547
  get documentation() {
7602
- return spaceTrim.spaceTrim(`
7548
+ return spaceTrim$1.spaceTrim(`
7603
7549
  # ${this.type}
7604
7550
 
7605
7551
  Defines specific actions or capabilities that the agent can perform.
@@ -7678,7 +7624,7 @@
7678
7624
  * Markdown documentation for DELETE commitment.
7679
7625
  */
7680
7626
  get documentation() {
7681
- return spaceTrim.spaceTrim(`
7627
+ return spaceTrim$1.spaceTrim(`
7682
7628
  # DELETE (CANCEL, DISCARD, REMOVE)
7683
7629
 
7684
7630
  A commitment to remove or disregard certain information or context. This can be useful for overriding previous commitments or removing unwanted behaviors.
@@ -7794,7 +7740,7 @@
7794
7740
  * Markdown documentation for FORMAT commitment.
7795
7741
  */
7796
7742
  get documentation() {
7797
- return spaceTrim.spaceTrim(`
7743
+ return spaceTrim$1.spaceTrim(`
7798
7744
  # ${this.type}
7799
7745
 
7800
7746
  Defines the specific output structure and formatting for responses (data formats, templates, structure).
@@ -7869,7 +7815,7 @@
7869
7815
  * Markdown documentation for GOAL commitment.
7870
7816
  */
7871
7817
  get documentation() {
7872
- return spaceTrim.spaceTrim(`
7818
+ return spaceTrim$1.spaceTrim(`
7873
7819
  # ${this.type}
7874
7820
 
7875
7821
  Defines the main goal which should be achieved by the AI assistant. There can be multiple goals, and later goals are more important than earlier goals.
@@ -7965,7 +7911,7 @@
7965
7911
  * Markdown documentation for KNOWLEDGE commitment.
7966
7912
  */
7967
7913
  get documentation() {
7968
- return spaceTrim.spaceTrim(`
7914
+ return spaceTrim$1.spaceTrim(`
7969
7915
  # ${this.type}
7970
7916
 
7971
7917
  Adds specific knowledge, facts, or context to the agent using a RAG (Retrieval-Augmented Generation) approach for external sources.
@@ -8082,7 +8028,7 @@
8082
8028
  * Markdown documentation for MEMORY commitment.
8083
8029
  */
8084
8030
  get documentation() {
8085
- return spaceTrim.spaceTrim(`
8031
+ return spaceTrim$1.spaceTrim(`
8086
8032
  # ${this.type}
8087
8033
 
8088
8034
  Similar to KNOWLEDGE but focuses on remembering past interactions and user preferences. This commitment helps the agent maintain context about the user's history, preferences, and previous conversations.
@@ -8184,7 +8130,7 @@
8184
8130
  * Markdown documentation for MESSAGE commitment.
8185
8131
  */
8186
8132
  get documentation() {
8187
- return spaceTrim.spaceTrim(`
8133
+ return spaceTrim$1.spaceTrim(`
8188
8134
  # ${this.type}
8189
8135
 
8190
8136
  Contains 1:1 text of the message which AI assistant already sent during the conversation. Later messages are later in the conversation. It is similar to EXAMPLE but it is not example, it is the real message which AI assistant already sent.
@@ -8302,7 +8248,7 @@
8302
8248
  * Markdown documentation for META commitment.
8303
8249
  */
8304
8250
  get documentation() {
8305
- return spaceTrim.spaceTrim(`
8251
+ return spaceTrim$1.spaceTrim(`
8306
8252
  # META
8307
8253
 
8308
8254
  Sets meta-information about the agent that is used for display and attribution purposes.
@@ -8438,7 +8384,7 @@
8438
8384
  * Markdown documentation for MODEL commitment.
8439
8385
  */
8440
8386
  get documentation() {
8441
- return spaceTrim.spaceTrim(`
8387
+ return spaceTrim$1.spaceTrim(`
8442
8388
  # ${this.type}
8443
8389
 
8444
8390
  Enforces technical parameters for the AI model, ensuring consistent behavior across different execution environments.
@@ -8673,7 +8619,7 @@
8673
8619
  * Markdown documentation for NOTE commitment.
8674
8620
  */
8675
8621
  get documentation() {
8676
- return spaceTrim.spaceTrim(`
8622
+ return spaceTrim$1.spaceTrim(`
8677
8623
  # ${this.type}
8678
8624
 
8679
8625
  Adds comments for documentation without changing agent behavior.
@@ -8775,7 +8721,7 @@
8775
8721
  * Markdown documentation for PERSONA commitment.
8776
8722
  */
8777
8723
  get documentation() {
8778
- return spaceTrim.spaceTrim(`
8724
+ return spaceTrim$1.spaceTrim(`
8779
8725
  # ${this.type}
8780
8726
 
8781
8727
  Defines who the agent is, their background, expertise, and personality traits.
@@ -8901,7 +8847,7 @@
8901
8847
  * Markdown documentation for RULE/RULES commitment.
8902
8848
  */
8903
8849
  get documentation() {
8904
- return spaceTrim.spaceTrim(`
8850
+ return spaceTrim$1.spaceTrim(`
8905
8851
  # ${this.type}
8906
8852
 
8907
8853
  Adds behavioral constraints and guidelines that the agent must follow.
@@ -8977,7 +8923,7 @@
8977
8923
  * Markdown documentation for SAMPLE/EXAMPLE commitment.
8978
8924
  */
8979
8925
  get documentation() {
8980
- return spaceTrim.spaceTrim(`
8926
+ return spaceTrim$1.spaceTrim(`
8981
8927
  # ${this.type}
8982
8928
 
8983
8929
  Provides examples of how the agent should respond or behave in certain situations.
@@ -9054,7 +9000,7 @@
9054
9000
  * Markdown documentation for SCENARIO commitment.
9055
9001
  */
9056
9002
  get documentation() {
9057
- return spaceTrim.spaceTrim(`
9003
+ return spaceTrim$1.spaceTrim(`
9058
9004
  # ${this.type}
9059
9005
 
9060
9006
  Defines a specific situation or context in which the AI assistant should operate. It helps to set the scene for the AI's responses. Later scenarios are more important than earlier scenarios.
@@ -9170,7 +9116,7 @@
9170
9116
  * Markdown documentation for STYLE commitment.
9171
9117
  */
9172
9118
  get documentation() {
9173
- return spaceTrim.spaceTrim(`
9119
+ return spaceTrim$1.spaceTrim(`
9174
9120
  # ${this.type}
9175
9121
 
9176
9122
  Defines how the agent should format and present its responses (tone, writing style, formatting).
@@ -9239,7 +9185,7 @@
9239
9185
  * Markdown documentation available at runtime.
9240
9186
  */
9241
9187
  get documentation() {
9242
- return spaceTrim.spaceTrim(`
9188
+ return spaceTrim$1.spaceTrim(`
9243
9189
  # ${this.type}
9244
9190
 
9245
9191
  This commitment is not yet fully implemented.
@@ -9413,7 +9359,7 @@
9413
9359
  const fullContent = currentCommitment.contentLines.join('\n');
9414
9360
  commitments.push({
9415
9361
  type: currentCommitment.type,
9416
- content: spaceTrim.spaceTrim(fullContent),
9362
+ content: spaceTrim$1.spaceTrim(fullContent),
9417
9363
  originalLine: currentCommitment.originalStartLine,
9418
9364
  lineNumber: currentCommitment.startLineNumber,
9419
9365
  });
@@ -9449,7 +9395,7 @@
9449
9395
  const fullContent = currentCommitment.contentLines.join('\n');
9450
9396
  commitments.push({
9451
9397
  type: currentCommitment.type,
9452
- content: spaceTrim.spaceTrim(fullContent),
9398
+ content: spaceTrim$1.spaceTrim(fullContent),
9453
9399
  originalLine: currentCommitment.originalStartLine,
9454
9400
  lineNumber: currentCommitment.startLineNumber,
9455
9401
  });
@@ -9933,6 +9879,7 @@
9933
9879
  /**
9934
9880
  * Default book
9935
9881
  *
9882
+ * @deprecated Use `$generateBookBoilerplate` instead
9936
9883
  * @public exported from `@promptbook/core`
9937
9884
  */
9938
9885
  const DEFAULT_BOOK = padBook(validateBook(spaceTrim__default["default"](`
@@ -9941,9 +9888,204 @@
9941
9888
  PERSONA A friendly AI assistant that helps you with your tasks
9942
9889
  `)));
9943
9890
  // <- Note: Not using book`...` notation to avoid strange error in jest unit tests `TypeError: (0 , book_notation_1.book) is not a function`
9944
- // <- TODO: !!! GENESIS_BOOK
9891
+ // <- TODO: !!! `GENESIS_BOOK` / `ADAM_BOOK` in `/agents/adam.book`
9945
9892
  // <- !!! Buttons into genesis book
9946
- // <- TODO: !!! createBookBoilerplate and deprecate `DEFAULT_BOOK`
9893
+ // <- TODO: !!! generateBookBoilerplate and deprecate `DEFAULT_BOOK`
9894
+
9895
+ /**
9896
+ * Trims string from all 4 sides
9897
+ *
9898
+ * Note: This is a re-exported function from the `spacetrim` package which is
9899
+ * Developed by same author @hejny as this package
9900
+ *
9901
+ * @public exported from `@promptbook/utils`
9902
+ * @see https://github.com/hejny/spacetrim#usage
9903
+ */
9904
+ const spaceTrim = spaceTrim$1.spaceTrim;
9905
+
9906
+ /**
9907
+ * Agent collection stored in Supabase table
9908
+ *
9909
+ * Note: This object can work both from Node.js and browser environment depending on the Supabase client provided
9910
+ *
9911
+ * @public exported from `@promptbook/core`
9912
+ * <- TODO: !!! Move to `@promptbook/supabase` package
9913
+ */
9914
+ class AgentCollectionInSupabase /* TODO: !!!! implements AgentCollection */ {
9915
+ /**
9916
+ * @param rootPath - path to the directory with agents
9917
+ * @param tools - Execution tools to be used in !!! `Agent` itself and listing the agents
9918
+ * @param options - Options for the collection creation
9919
+ */
9920
+ constructor(supabaseClient,
9921
+ /// TODO: !!! Remove> private readonly tools?: Pick<ExecutionTools, 'llm' | 'fs' | 'scrapers'>,
9922
+ options) {
9923
+ this.supabaseClient = supabaseClient;
9924
+ this.options = options;
9925
+ const { isVerbose = exports.DEFAULT_IS_VERBOSE } = options || {};
9926
+ if (isVerbose) {
9927
+ console.info(`Creating pipeline collection from supabase...`);
9928
+ }
9929
+ }
9930
+ /**
9931
+ * Cached defined execution tools
9932
+ */
9933
+ // !!! private _definedTools: ExecutionTools | null = null;
9934
+ /*
9935
+ TODO: !!! Use or remove
9936
+ /**
9937
+ * Gets or creates execution tools for the collection
9938
+ * /
9939
+ private async getTools(): Promise<ExecutionTools> {
9940
+ if (this._definedTools !== null) {
9941
+ return this._definedTools;
9942
+ }
9943
+
9944
+ this._definedTools = {
9945
+ ...(this.tools === undefined || this.tools.fs === undefined ? await $provideExecutionToolsForNode() : {}),
9946
+ ...this.tools,
9947
+ };
9948
+ return this._definedTools;
9949
+ }
9950
+ // <- TODO: [👪] Maybe create some common abstraction *(or parent abstract class)*
9951
+ */
9952
+ /**
9953
+ * Gets all agents in the collection
9954
+ */
9955
+ async listAgents( /* TODO: [🧠] Allow to pass some condition here */) {
9956
+ const { isVerbose = exports.DEFAULT_IS_VERBOSE } = this.options || {};
9957
+ const result = await this.supabaseClient
9958
+ .from('AgentCollection' /* <- TODO: !!!! Change to `Agent` */)
9959
+ .select('agentProfile');
9960
+ if (result.error) {
9961
+ throw new DatabaseError(spaceTrim((block) => `
9962
+
9963
+ Error fetching agents from Supabase:
9964
+
9965
+ ${block(result.error.message)}
9966
+ `));
9967
+ }
9968
+ if (isVerbose) {
9969
+ console.info(`Found ${result.data.length} agents in directory`);
9970
+ }
9971
+ return result.data.map((row) => row.agentProfile);
9972
+ }
9973
+ /**
9974
+ * !!!
9975
+ * /
9976
+ public async spawnAgent(agentName: string_agent_name): Promise<Agent> {
9977
+
9978
+ // <- TODO: !!! ENOENT: no such file or directory, open 'C:\Users\me\work\ai\promptbook\agents\examples\Asistent pro LŠVP.book
9979
+ const { isVerbose = DEFAULT_IS_VERBOSE } = this.options || {};
9980
+ const tools = await this.getTools();
9981
+
9982
+ const agentSourceValue = validateBook(await tools.fs!.readFile(agentSourcePath, 'utf-8'));
9983
+ const agentSource = new BehaviorSubject(agentSourceValue);
9984
+
9985
+ // Note: Write file whenever agent source changes
9986
+ agentSource.subscribe(async (newSource) => {
9987
+ if (isVerbose) {
9988
+ console.info(colors.cyan(`Writing agent source to file ${agentSourcePath}`));
9989
+ }
9990
+ await forTime(500); // <- TODO: [🙌] !!! Remove
9991
+ await tools.fs!.writeFile(agentSourcePath, newSource, 'utf-8');
9992
+ });
9993
+
9994
+ // Note: Watch file for external changes
9995
+ for await (const event of tools.fs!.watch(agentSourcePath)) {
9996
+ // <- TODO: !!!! Solve the memory freeing when the watching is no longer needed
9997
+
9998
+ if (event.eventType !== 'change') {
9999
+ continue;
10000
+ }
10001
+
10002
+ if (isVerbose) {
10003
+ console.info(
10004
+ colors.cyan(`Detected external change in agent source file ${agentSourcePath}, reloading`),
10005
+ );
10006
+ }
10007
+ await forTime(500); // <- TODO: [🙌] !!! Remove
10008
+ const newSource = validateBook(await tools.fs!.readFile(agentSourcePath, 'utf-8'));
10009
+ agentSource.next(newSource);
10010
+ }
10011
+
10012
+ // TODO: [🙌] !!!! Debug the infinite loop when file is changed externally and agent source is updated which causes file to be written again
10013
+
10014
+ const agent = new Agent({
10015
+ ...this.options,
10016
+ agentSource,
10017
+ executionTools: this.tools || {},
10018
+ });
10019
+
10020
+ if (isVerbose) {
10021
+ console.info(colors.cyan(`Created agent "${agent.agentName}" from source file ${agentSourcePath}`));
10022
+ }
10023
+
10024
+ return agent;
10025
+ * /
10026
+ }
10027
+ */
10028
+ /**
10029
+ * !!!@@@
10030
+ */
10031
+ async getAgentSource(agentName) {
10032
+ const result = await this.supabaseClient
10033
+ .from('AgentCollection' /* <- TODO: !!!! Change to `Agent` */)
10034
+ .select('agentSource')
10035
+ .eq('agentName', agentName)
10036
+ .single();
10037
+ if (result.error) {
10038
+ throw new DatabaseError(spaceTrim((block) => `
10039
+
10040
+ Error fetching agent "${agentName}" from Supabase:
10041
+
10042
+ ${block(result.error.message)}
10043
+ `));
10044
+ // <- TODO: !!! First check if the error is "not found" and throw `NotFoundError` instead then throw `DatabaseError`
10045
+ }
10046
+ const agentSource = new rxjs.BehaviorSubject(result.data.agentSource);
10047
+ // <- TODO: !!!! Dynamic updates
10048
+ return agentSource;
10049
+ }
10050
+ /**
10051
+ * Creates a new agent in the collection
10052
+ *
10053
+ * Note: You can set 'PARENT' in the agent source to inherit from another agent in the collection.
10054
+ */
10055
+ async createAgent(agentSource) {
10056
+ const agentProfile = parseAgentSource(agentSource);
10057
+ // <- TODO: [🕛]
10058
+ const result = await this.supabaseClient.from('AgentCollection' /* <- TODO: !!!! Change to `Agent` */).insert({
10059
+ agentName: agentProfile.agentName || '!!!!!' /* <- TODO: !!!! Remove */,
10060
+ agentProfile,
10061
+ createdAt: new Date().toISOString(),
10062
+ updatedAt: null,
10063
+ agentVersion: 0,
10064
+ promptbookEngineVersion: PROMPTBOOK_ENGINE_VERSION,
10065
+ usage: ZERO_USAGE,
10066
+ agentSource: agentSource,
10067
+ });
10068
+ if (result.error) {
10069
+ throw new DatabaseError(spaceTrim((block) => `
10070
+ Error creating agent "${agentProfile.agentName}" in Supabase:
10071
+
10072
+ ${block(result.error.message)}
10073
+ `));
10074
+ }
10075
+ return agentProfile;
10076
+ }
10077
+ /**
10078
+ * Deletes an agent from the collection
10079
+ */
10080
+ async deleteAgent(agentName) {
10081
+ throw new NotYetImplementedError('Method not implemented.');
10082
+ }
10083
+ }
10084
+ /**
10085
+ * TODO: !!!! Implement it here correctly and update JSDoc comments here, and on interface + other implementations
10086
+ * TODO: Write unit test
10087
+ * TODO: [🧠][🚙] `AgentXxx` vs `AgentsXxx` naming convention
10088
+ */
9947
10089
 
9948
10090
  /**
9949
10091
  * Constructs `PipelineCollection` from async sources
@@ -10042,7 +10184,7 @@
10042
10184
  }
10043
10185
  async function getPipelineByUrl(url) {
10044
10186
  if (!predicate(url)) {
10045
- throw new NotFoundError(await spaceTrim.spaceTrim(async (block) => `
10187
+ throw new NotFoundError(await spaceTrim$1.spaceTrim(async (block) => `
10046
10188
  Promptbook with url "${url}" not found or not accessible
10047
10189
 
10048
10190
  Available promptbooks:
@@ -12365,7 +12507,7 @@
12365
12507
  function getParserForCommand(command) {
12366
12508
  const commandParser = COMMANDS.find((commandParser) => commandParser.name === command.type);
12367
12509
  if (commandParser === undefined) {
12368
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
12510
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
12369
12511
  Command ${command.type} parser is not found
12370
12512
 
12371
12513
  ${block(JSON.stringify(command, null, 4)
@@ -12441,7 +12583,7 @@
12441
12583
  .map(removeMarkdownFormatting)
12442
12584
  .map((item) => item.trim());
12443
12585
  if (items.length === 0 || items[0] === '') {
12444
- throw new ParseError(spaceTrim.spaceTrim((block) => `
12586
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
12445
12587
  Malformed command:
12446
12588
  - ${raw}
12447
12589
 
@@ -12477,7 +12619,7 @@
12477
12619
  return command;
12478
12620
  }
12479
12621
  }
12480
- throw new ParseError(spaceTrim.spaceTrim((block) => `
12622
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
12481
12623
  Malformed or unknown command:
12482
12624
  - ${raw}
12483
12625
 
@@ -12528,7 +12670,7 @@
12528
12670
  if (!(error instanceof ParseError)) {
12529
12671
  throw error;
12530
12672
  }
12531
- throw new ParseError(spaceTrim.spaceTrim((block) => `
12673
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
12532
12674
  Invalid ${commandName} command:
12533
12675
 
12534
12676
  Your command:
@@ -12802,7 +12944,7 @@
12802
12944
  * @public exported from `@promptbook/markdown-utils`
12803
12945
  */
12804
12946
  function removeMarkdownComments(content) {
12805
- return spaceTrim.spaceTrim(content.replace(/<!--(.*?)-->/gs, ''));
12947
+ return spaceTrim$1.spaceTrim(content.replace(/<!--(.*?)-->/gs, ''));
12806
12948
  }
12807
12949
 
12808
12950
  /**
@@ -13118,7 +13260,7 @@
13118
13260
  if (pipelineString.startsWith('#!')) {
13119
13261
  const [shebangLine, ...restLines] = pipelineString.split('\n');
13120
13262
  if (!(shebangLine || '').includes('ptbk')) {
13121
- throw new ParseError(spaceTrim.spaceTrim((block) => `
13263
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
13122
13264
  It seems that you try to parse a book file which has non-standard shebang line for book files:
13123
13265
  Shebang line must contain 'ptbk'
13124
13266
 
@@ -13134,7 +13276,7 @@
13134
13276
  pipelineString = validatePipelineString(restLines.join('\n'));
13135
13277
  }
13136
13278
  pipelineString = removeMarkdownComments(pipelineString);
13137
- pipelineString = spaceTrim.spaceTrim(pipelineString);
13279
+ pipelineString = spaceTrim$1.spaceTrim(pipelineString);
13138
13280
  // <- TODO: [😧] `spaceTrim` should preserve discriminated type *(or at lease `PipelineString`)*
13139
13281
  pipelineString = deflatePipeline(pipelineString);
13140
13282
  // ==============
@@ -13146,7 +13288,7 @@
13146
13288
  // ==============
13147
13289
  // Note: 1️⃣◽4️⃣ Check markdown structure
13148
13290
  if (pipelineHead === undefined) {
13149
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
13291
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
13150
13292
  Pipeline head is not defined
13151
13293
 
13152
13294
  ${block(getPipelineIdentification())}
@@ -13155,7 +13297,7 @@
13155
13297
  `));
13156
13298
  }
13157
13299
  if (pipelineHead.level !== 1) {
13158
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
13300
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
13159
13301
  Pipeline head is not h1
13160
13302
 
13161
13303
  ${block(getPipelineIdentification())}
@@ -13164,7 +13306,7 @@
13164
13306
  `));
13165
13307
  }
13166
13308
  if (!pipelineSections.every((section) => section.level === 2)) {
13167
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
13309
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
13168
13310
  Not every pipeline section is h2
13169
13311
 
13170
13312
  ${block(getPipelineIdentification())}
@@ -13177,7 +13319,7 @@
13177
13319
  const defineParam = (parameterCommand) => {
13178
13320
  const { parameterName, parameterDescription, isInput, isOutput } = parameterCommand;
13179
13321
  if (RESERVED_PARAMETER_NAMES.includes(parameterName)) {
13180
- throw new ParseError(spaceTrim.spaceTrim((block) => `
13322
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
13181
13323
  Parameter name {${parameterName}} is reserved and cannot be used as resulting parameter name
13182
13324
 
13183
13325
  ${block(getPipelineIdentification())}
@@ -13188,7 +13330,7 @@
13188
13330
  existingParameter.description &&
13189
13331
  existingParameter.description !== parameterDescription &&
13190
13332
  parameterDescription) {
13191
- throw new ParseError(spaceTrim.spaceTrim((block) => `
13333
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
13192
13334
  Parameter \`{${parameterName}}\` is defined multiple times with different description:
13193
13335
 
13194
13336
  ${block(getPipelineIdentification())}
@@ -13226,7 +13368,7 @@
13226
13368
  description = description.split(/^>.*$/gm).join('');
13227
13369
  //Note: Remove lists and return statement - TODO: [🎾] Make util (exported from `@promptbool/utils`)
13228
13370
  description = description.split(/^(?:(?:-)|(?:\d\))|(?:`?->))\s+.*$/gm).join('');
13229
- description = spaceTrim.spaceTrim(description);
13371
+ description = spaceTrim$1.spaceTrim(description);
13230
13372
  if (description === '') {
13231
13373
  description = undefined;
13232
13374
  }
@@ -13237,7 +13379,7 @@
13237
13379
  const command = parseCommand(listItem, 'PIPELINE_HEAD');
13238
13380
  const commandParser = getParserForCommand(command);
13239
13381
  if (commandParser.isUsedInPipelineHead !== true /* <- Note: [🦦][4] */) {
13240
- throw new ParseError(spaceTrim.spaceTrim((block) => `
13382
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
13241
13383
  Command \`${command.type}\` is not allowed in the head of the pipeline ONLY at the pipeline task
13242
13384
 
13243
13385
  ${block(getPipelineIdentification())}
@@ -13251,7 +13393,7 @@
13251
13393
  if (!(error instanceof ParseError)) {
13252
13394
  throw error;
13253
13395
  }
13254
- throw new ParseError(spaceTrim.spaceTrim((block) => `
13396
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
13255
13397
  Command ${command.type} failed to apply to the pipeline
13256
13398
 
13257
13399
  The error:
@@ -13304,7 +13446,7 @@
13304
13446
  description = description.split(/^>.*$/gm).join('');
13305
13447
  //Note: Remove lists and return statement - TODO: [🎾]
13306
13448
  description = description.split(/^(?:(?:-)|(?:\d\))|(?:`?->))\s+.*$/gm).join('');
13307
- description = spaceTrim.spaceTrim(description);
13449
+ description = spaceTrim$1.spaceTrim(description);
13308
13450
  if (description === '') {
13309
13451
  description = undefined;
13310
13452
  }
@@ -13338,7 +13480,7 @@
13338
13480
  for (const { listItem, command } of commands) {
13339
13481
  const commandParser = getParserForCommand(command);
13340
13482
  if (commandParser.isUsedInPipelineTask !== true /* <- Note: [🦦][4] */) {
13341
- throw new ParseError(spaceTrim.spaceTrim((block) => `
13483
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
13342
13484
  Command \`${command.type}\` is not allowed in the task of the promptbook ONLY at the pipeline head
13343
13485
 
13344
13486
  ${block(getPipelineIdentification())}
@@ -13353,7 +13495,7 @@
13353
13495
  if (!(error instanceof ParseError)) {
13354
13496
  throw error;
13355
13497
  }
13356
- throw new ParseError(spaceTrim.spaceTrim((block) => `
13498
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
13357
13499
  Command \`${command.type}\` failed to apply to the task
13358
13500
 
13359
13501
  The error:
@@ -13384,14 +13526,14 @@
13384
13526
  // TODO: [🍧] Should be done in SECTION command
13385
13527
  if ($taskJson.taskType === 'SCRIPT_TASK') {
13386
13528
  if (!language) {
13387
- throw new ParseError(spaceTrim.spaceTrim((block) => `
13529
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
13388
13530
  You must specify the language of the script in the \`SCRIPT\` task
13389
13531
 
13390
13532
  ${block(getPipelineIdentification())}
13391
13533
  `));
13392
13534
  }
13393
13535
  if (!SUPPORTED_SCRIPT_LANGUAGES.includes(language)) {
13394
- throw new ParseError(spaceTrim.spaceTrim((block) => `
13536
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
13395
13537
  Script language ${language} is not supported.
13396
13538
 
13397
13539
  Supported languages are:
@@ -13553,7 +13695,7 @@
13553
13695
  const warningLine = `<!-- ${GENERATOR_WARNING} -->`;
13554
13696
  const sectionRegex = new RegExp(`<!--${sectionName}-->([\\s\\S]*?)<!--/${sectionName}-->`, 'g');
13555
13697
  const sectionMatch = content.match(sectionRegex);
13556
- const contentToInsert = spaceTrim.spaceTrim((block) => `
13698
+ const contentToInsert = spaceTrim$1.spaceTrim((block) => `
13557
13699
  <!--${sectionName}-->
13558
13700
  ${block(warningLine)}
13559
13701
  ${block(sectionContent)}
@@ -13566,7 +13708,7 @@
13566
13708
  const placeForSection = removeMarkdownComments(content).match(/^##.*$/im);
13567
13709
  if (placeForSection !== null) {
13568
13710
  const [heading] = placeForSection;
13569
- return content.replace(heading, spaceTrim.spaceTrim((block) => `
13711
+ return content.replace(heading, spaceTrim$1.spaceTrim((block) => `
13570
13712
  ${block(contentToInsert)}
13571
13713
 
13572
13714
  ${block(heading)}
@@ -13575,7 +13717,7 @@
13575
13717
  console.warn(`No place where to put the section <!--${sectionName}-->, using the end of the file`);
13576
13718
  // <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
13577
13719
  // <- TODO: [🏮] Some better way how to get warnings from pipeline parsing / logic
13578
- return spaceTrim.spaceTrim((block) => `
13720
+ return spaceTrim$1.spaceTrim((block) => `
13579
13721
  ${block(content)}
13580
13722
 
13581
13723
  ${block(contentToInsert)}
@@ -13651,7 +13793,7 @@
13651
13793
  .filter(([MERMAID_NAME]) => (inputAndIntermediateParametersMermaid + outputParametersMermaid).includes(MERMAID_NAME))
13652
13794
  .map(([MERMAID_NAME, title]) => `${MERMAID_NAME}((${title})):::${MERMAID_NAME}`)
13653
13795
  .join('\n');
13654
- const promptbookMermaid = spaceTrim.spaceTrim((block) => `
13796
+ const promptbookMermaid = spaceTrim$1.spaceTrim((block) => `
13655
13797
 
13656
13798
  %% 🔮 Tip: Open this on GitHub or in the VSCode website to see the Mermaid graph visually
13657
13799
 
@@ -13707,7 +13849,7 @@
13707
13849
  return { href: `#${task.name}`, title: task.title };
13708
13850
  },
13709
13851
  });
13710
- const promptbookMermaidBlock = spaceTrim.spaceTrim((block) => `
13852
+ const promptbookMermaidBlock = spaceTrim$1.spaceTrim((block) => `
13711
13853
  \`\`\`mermaid
13712
13854
  ${block(promptbookMermaid)}
13713
13855
  \`\`\`
@@ -13745,7 +13887,7 @@
13745
13887
  async promptDialog(options) {
13746
13888
  const answer = await this.options.callback(options);
13747
13889
  if (this.options.isVerbose) {
13748
- console.info(spaceTrim.spaceTrim((block) => `
13890
+ console.info(spaceTrim$1.spaceTrim((block) => `
13749
13891
  📖 ${block(options.promptTitle)}
13750
13892
  👤 ${block(answer)}
13751
13893
  `));
@@ -13886,7 +14028,7 @@
13886
14028
  function executionReportJsonToString(executionReportJson, options) {
13887
14029
  var _a, _b, _c, _d, _e, _f;
13888
14030
  const { taxRate, chartsWidth } = { ...ExecutionReportStringOptionsDefaults, ...(options || {}) };
13889
- let executionReportString = spaceTrim.spaceTrim((block) => `
14031
+ let executionReportString = spaceTrim$1.spaceTrim((block) => `
13890
14032
  # ${executionReportJson.title || 'Execution report'}
13891
14033
 
13892
14034
  ${block(executionReportJson.description || '')}
@@ -14008,7 +14150,7 @@
14008
14150
  if (just(true)) {
14009
14151
  executionReportString +=
14010
14152
  '\n\n\n\n' +
14011
- spaceTrim.spaceTrim((block) => {
14153
+ spaceTrim$1.spaceTrim((block) => {
14012
14154
  var _a;
14013
14155
  return `
14014
14156
 
@@ -14027,7 +14169,7 @@
14027
14169
  executionReportString += '*No result*';
14028
14170
  }
14029
14171
  else if (typeof promptExecution.result.content === 'string') {
14030
- executionReportString += spaceTrim.spaceTrim((block) => `
14172
+ executionReportString += spaceTrim$1.spaceTrim((block) => `
14031
14173
  \`\`\`
14032
14174
  ${block(escapeMarkdownBlock(promptExecution.result.content))}
14033
14175
  \`\`\`
@@ -14040,7 +14182,7 @@
14040
14182
  if (promptExecution.error && promptExecution.error.message) {
14041
14183
  executionReportString +=
14042
14184
  '\n\n\n\n' +
14043
- spaceTrim.spaceTrim((block) => `
14185
+ spaceTrim$1.spaceTrim((block) => `
14044
14186
 
14045
14187
  ### Error
14046
14188
 
@@ -14799,66 +14941,6 @@
14799
14941
  * TODO: [🧠] Maybe `BehaviorSubject` is too heavy for this use case, maybe just tuple `[value,setValue]` is enough
14800
14942
  */
14801
14943
 
14802
- /**
14803
- * Represents one AI Agent
14804
- *
14805
- * Note: [🦖] There are several different things in Promptbook:
14806
- * - `Agent` - which represents an AI Agent with its source, memories, actions, etc. Agent is a higher-level abstraction which is internally using:
14807
- * - `LlmExecutionTools` - which wraps one or more LLM models and provides an interface to execute them
14808
- * - `AgentLlmExecutionTools` - which is a specific implementation of `LlmExecutionTools` that wraps another LlmExecutionTools and applies agent-specific system prompts and requirements
14809
- * - `OpenAiAssistantExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities, recommended for usage in `Agent` or `AgentLlmExecutionTools`
14810
- *
14811
- * @public exported from `@promptbook/core`
14812
- */
14813
- class Agent {
14814
- /**
14815
- * Not used in Agent, always returns empty array
14816
- */
14817
- get parameters() {
14818
- return [
14819
- /* [😰] */
14820
- ];
14821
- }
14822
- constructor(options) {
14823
- this.options = options;
14824
- /**
14825
- * Name of the agent
14826
- */
14827
- this.agentName = null;
14828
- /**
14829
- * Description of the agent
14830
- */
14831
- this.personaDescription = null;
14832
- /**
14833
- * Metadata like image or color
14834
- */
14835
- this.meta = {};
14836
- this.agentSource = asUpdatableSubject(options.agentSource);
14837
- this.agentSource.subscribe((source) => {
14838
- const { agentName, personaDescription, meta } = parseAgentSource(source);
14839
- this.agentName = agentName;
14840
- this.personaDescription = personaDescription;
14841
- this.meta = { ...this.meta, ...meta };
14842
- });
14843
- }
14844
- /**
14845
- * Creates LlmExecutionTools which exposes the agent as a model
14846
- */
14847
- getLlmExecutionTools() {
14848
- const llmTools = new AgentLlmExecutionTools({
14849
- llmTools: getSingleLlmExecutionTools(this.options.executionTools.llm),
14850
- agentSource: this.agentSource.value, // <- TODO: !!!! Allow to pass BehaviorSubject<string_book> OR refresh llmExecutionTools.callChat on agentSource change
14851
- });
14852
- // TODO: !!!! Add `Agent` simple "mocked" learning by appending to agent source
14853
- // TODO: !!!! Add `Agent` learning by promptbookAgent
14854
- return llmTools;
14855
- }
14856
- }
14857
- /**
14858
- * TODO: [🧠][😰]Agent is not working with the parameters, should it be?
14859
- * TODO: !!! Agent on remote server
14860
- */
14861
-
14862
14944
  /**
14863
14945
  * Change ellipsis character to three dots `…` -> `...`
14864
14946
  *
@@ -15048,7 +15130,7 @@
15048
15130
  /**
15049
15131
  * List of available OpenAI models with pricing
15050
15132
  *
15051
- * Note: Synced with official API docs at 2025-08-20
15133
+ * Note: Synced with official API docs at 2025-11-19
15052
15134
  *
15053
15135
  * @see https://platform.openai.com/docs/models/
15054
15136
  * @see https://openai.com/api/pricing/
@@ -15058,11 +15140,21 @@
15058
15140
  name: 'OPENAI_MODELS',
15059
15141
  value: [
15060
15142
  /**/
15143
+ {
15144
+ modelVariant: 'CHAT',
15145
+ modelTitle: 'gpt-5.1',
15146
+ modelName: 'gpt-5.1',
15147
+ modelDescription: 'The best model for coding and agentic tasks with configurable reasoning effort.',
15148
+ pricing: {
15149
+ prompt: pricing(`$1.25 / 1M tokens`),
15150
+ output: pricing(`$10.00 / 1M tokens`),
15151
+ },
15152
+ },
15061
15153
  {
15062
15154
  modelVariant: 'CHAT',
15063
15155
  modelTitle: 'gpt-5',
15064
15156
  modelName: 'gpt-5',
15065
- modelDescription: "OpenAI's most advanced language model with unprecedented reasoning capabilities and 200K context window. Features revolutionary improvements in complex problem-solving, scientific reasoning, and creative tasks. Demonstrates human-level performance across diverse domains with enhanced safety measures and alignment. Represents the next generation of AI with superior understanding, nuanced responses, and advanced multimodal capabilities.",
15157
+ modelDescription: "OpenAI's most advanced language model with unprecedented reasoning capabilities and 200K context window. Features revolutionary improvements in complex problem-solving, scientific reasoning, and creative tasks. Demonstrates human-level performance across diverse domains with enhanced safety measures and alignment. Represents the next generation of AI with superior understanding, nuanced responses, and advanced multimodal capabilities. DEPRECATED: Use gpt-5.1 instead.",
15066
15158
  pricing: {
15067
15159
  prompt: pricing(`$1.25 / 1M tokens`),
15068
15160
  output: pricing(`$10.00 / 1M tokens`),
@@ -16623,11 +16715,11 @@
16623
16715
  if (!this.isCreatingNewAssistantsAllowed) {
16624
16716
  throw new NotAllowed(`Creating new assistants is not allowed. Set \`isCreatingNewAssistantsAllowed: true\` in options to enable this feature.`);
16625
16717
  }
16626
- await this.playground();
16718
+ // await this.playground();
16627
16719
  const { name, instructions } = options;
16628
16720
  const client = await this.getClient();
16629
- /*
16630
- TODO: !!!
16721
+ /*/
16722
+ //TODO: !!!
16631
16723
  async function downloadFile(url: string, folder = './tmp'): Promise<string> {
16632
16724
  const filename = path.basename(url.split('?')[0]);
16633
16725
  const filepath = path.join(folder, filename);
@@ -16671,8 +16763,8 @@
16671
16763
  const file = await uploadFileToOpenAI(filepath);
16672
16764
  uploadedFiles.push(file.id);
16673
16765
  }
16674
- */
16675
- alert('!!!! Creating new OpenAI assistant');
16766
+ /**/
16767
+ // alert('!!!! Creating new OpenAI assistant');
16676
16768
  // 3️⃣ Create assistant with uploaded files
16677
16769
  const assistant = await client.beta.assistants.create({
16678
16770
  name,
@@ -16833,15 +16925,27 @@
16833
16925
  const chatPrompt = prompt;
16834
16926
  let underlyingLlmResult;
16835
16927
  if (OpenAiAssistantExecutionTools.isOpenAiAssistantExecutionTools(this.options.llmTools)) {
16928
+ if (this.options.isVerbose) {
16929
+ console.log(`Creating new OpenAI Assistant for agent ${this.title}...`);
16930
+ }
16836
16931
  // <- TODO: !!! Check also `isCreatingNewAssistantsAllowed` and warn about it
16837
16932
  const assistant = await this.options.llmTools.createNewAssistant({
16838
16933
  name: this.title,
16839
16934
  instructions: modelRequirements.systemMessage,
16935
+ /*
16936
+ !!!
16937
+ metadata: {
16938
+ agentModelName: this.modelName,
16939
+ }
16940
+ */
16840
16941
  });
16841
16942
  // <- TODO: !!! Cache the assistant in prepareCache
16842
16943
  underlyingLlmResult = await assistant.callChatModel(chatPrompt);
16843
16944
  }
16844
16945
  else {
16946
+ if (this.options.isVerbose) {
16947
+ console.log(`Creating Assistant ${this.title} on generic LLM execution tools...`);
16948
+ }
16845
16949
  // Create modified chat prompt with agent system message
16846
16950
  const modifiedChatPrompt = {
16847
16951
  ...chatPrompt,
@@ -16875,6 +16979,67 @@
16875
16979
  * TODO: [🧠] Adding parameter substitution support (here or should be responsibility of the underlying LLM Tools)
16876
16980
  */
16877
16981
 
16982
+ /**
16983
+ * Represents one AI Agent
16984
+ *
16985
+ * Note: [🦖] There are several different things in Promptbook:
16986
+ * - `Agent` - which represents an AI Agent with its source, memories, actions, etc. Agent is a higher-level abstraction which is internally using:
16987
+ * - `LlmExecutionTools` - which wraps one or more LLM models and provides an interface to execute them
16988
+ * - `AgentLlmExecutionTools` - which is a specific implementation of `LlmExecutionTools` that wraps another LlmExecutionTools and applies agent-specific system prompts and requirements
16989
+ * - `OpenAiAssistantExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities, recommended for usage in `Agent` or `AgentLlmExecutionTools`
16990
+ *
16991
+ * @public exported from `@promptbook/core`
16992
+ */
16993
+ class Agent {
16994
+ /**
16995
+ * Not used in Agent, always returns empty array
16996
+ */
16997
+ get parameters() {
16998
+ return [
16999
+ /* [😰] */
17000
+ ];
17001
+ }
17002
+ constructor(options) {
17003
+ this.options = options;
17004
+ /**
17005
+ * Name of the agent
17006
+ */
17007
+ this.agentName = null;
17008
+ /**
17009
+ * Description of the agent
17010
+ */
17011
+ this.personaDescription = null;
17012
+ /**
17013
+ * Metadata like image or color
17014
+ */
17015
+ this.meta = {};
17016
+ this.agentSource = asUpdatableSubject(options.agentSource);
17017
+ this.agentSource.subscribe((source) => {
17018
+ const { agentName, personaDescription, meta } = parseAgentSource(source);
17019
+ this.agentName = agentName;
17020
+ this.personaDescription = personaDescription;
17021
+ this.meta = { ...this.meta, ...meta };
17022
+ });
17023
+ }
17024
+ /**
17025
+ * Creates LlmExecutionTools which exposes the agent as a model
17026
+ */
17027
+ getLlmExecutionTools() {
17028
+ const llmTools = new AgentLlmExecutionTools({
17029
+ isVerbose: this.options.isVerbose,
17030
+ llmTools: getSingleLlmExecutionTools(this.options.executionTools.llm),
17031
+ agentSource: this.agentSource.value, // <- TODO: !!!! Allow to pass BehaviorSubject<string_book> OR refresh llmExecutionTools.callChat on agentSource change
17032
+ });
17033
+ // TODO: !!!! Add `Agent` simple "mocked" learning by appending to agent source
17034
+ // TODO: !!!! Add `Agent` learning by promptbookAgent
17035
+ return llmTools;
17036
+ }
17037
+ }
17038
+ /**
17039
+ * TODO: [🧠][😰]Agent is not working with the parameters, should it be?
17040
+ * TODO: !!! Agent on remote server
17041
+ */
17042
+
16878
17043
  /**
16879
17044
  * Creates new AgentLlmExecutionTools that wrap underlying LLM tools with agent-specific behavior
16880
17045
  *
@@ -18107,6 +18272,25 @@
18107
18272
  },
18108
18273
  };
18109
18274
 
18275
+ /**
18276
+ * Returns information about the current runtime environment
18277
+ *
18278
+ * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environments
18279
+ *
18280
+ * @public exported from `@promptbook/utils`
18281
+ */
18282
+ function $detectRuntimeEnvironment() {
18283
+ return {
18284
+ isRunningInBrowser: $isRunningInBrowser(),
18285
+ isRunningInJest: $isRunningInJest(),
18286
+ isRunningInNode: $isRunningInNode(),
18287
+ isRunningInWebWorker: $isRunningInWebWorker(),
18288
+ };
18289
+ }
18290
+ /**
18291
+ * TODO: [🎺] Also detect and report node version here
18292
+ */
18293
+
18110
18294
  /**
18111
18295
  * Provide information about Promptbook, engine version, book language version, servers, ...
18112
18296
  *
@@ -18116,7 +18300,7 @@
18116
18300
  * @public exported from `@promptbook/core`
18117
18301
  */
18118
18302
  function aboutPromptbookInformation(options) {
18119
- const { isServersInfoIncluded = true } = options || {};
18303
+ const { isServersInfoIncluded = true, isRuntimeEnvironmentInfoIncluded = true } = options || {};
18120
18304
  const fullInfoPieces = [];
18121
18305
  const basicInfo = spaceTrim__default["default"](`
18122
18306
 
@@ -18140,6 +18324,22 @@
18140
18324
  `);
18141
18325
  fullInfoPieces.push(serversInfo);
18142
18326
  }
18327
+ if (isRuntimeEnvironmentInfoIncluded) {
18328
+ const runtimeEnvironment = $detectRuntimeEnvironment();
18329
+ const environmentInfoRecord = {
18330
+ ...runtimeEnvironment,
18331
+ isCostPrevented: IS_COST_PREVENTED,
18332
+ };
18333
+ const environmentInfo = spaceTrim__default["default"]((block) => `
18334
+
18335
+ ## Environment
18336
+
18337
+ ${block(Object.entries(environmentInfoRecord)
18338
+ .map(([key, value]) => `- **${key}:** ${valueToString(value)}`)
18339
+ .join('\n'))}
18340
+ `);
18341
+ fullInfoPieces.push(environmentInfo);
18342
+ }
18143
18343
  const fullInfo = spaceTrim__default["default"](fullInfoPieces.join('\n\n'));
18144
18344
  return fullInfo;
18145
18345
  }
@@ -18147,7 +18347,140 @@
18147
18347
  * TODO: [🗽] Unite branding and make single place for it
18148
18348
  */
18149
18349
 
18350
+ /**
18351
+ * Pick random item from the received array
18352
+ *
18353
+ * @private internal helper function
18354
+ */
18355
+ function $randomItem(...items) {
18356
+ if (items.length === 0) {
18357
+ throw new Error(`Not enough items`);
18358
+ }
18359
+ return items[Math.floor(Math.random( /* <- TODO: [🐉] Probably use seed random */) * items.length)];
18360
+ }
18361
+ /**
18362
+ * TODO: [🤶] Maybe export through `@promptbook/utils` or `@promptbook/random` package
18363
+ */
18364
+
18365
+ const FIRSTNAMES = [
18366
+ 'Paul',
18367
+ 'George',
18368
+ 'Adam',
18369
+ 'Lucy',
18370
+ 'Sophia',
18371
+ 'Emma',
18372
+ 'Olivia',
18373
+ 'Noah',
18374
+ 'Liam',
18375
+ 'Ethan',
18376
+ 'Ava',
18377
+ 'Mia',
18378
+ 'Isabella',
18379
+ 'James',
18380
+ 'Benjamin',
18381
+ 'Elijah',
18382
+ 'Sophia',
18383
+ 'Charlotte',
18384
+ 'Amelia',
18385
+ 'Harper',
18386
+ 'Alexander',
18387
+ 'William',
18388
+ 'Michael',
18389
+ 'Daniel',
18390
+ 'Matthew',
18391
+ 'Joseph',
18392
+ 'David',
18393
+ 'Samuel',
18394
+ 'Henry',
18395
+ 'Jack',
18396
+ 'Sebastian',
18397
+ 'Gabriel',
18398
+ 'Anthony',
18399
+ 'Christopher',
18400
+ ];
18401
+ const LASTNAMES_WITH_COLORS = [
18402
+ { lastname: 'Green', color: '#008000' },
18403
+ { lastname: 'Brown', color: '#A52A2A' },
18404
+ { lastname: 'Black', color: '#000000' },
18405
+ { lastname: 'White', color: '#FFFFFF' },
18406
+ { lastname: 'Gray', color: '#808080' },
18407
+ { lastname: 'Blue', color: '#0000FF' },
18408
+ ];
18409
+ /**
18410
+ *
18411
+ * @private internal helper function
18412
+ */
18413
+ function $randomFullnameWithColor() {
18414
+ const firstname = $randomItem(...FIRSTNAMES);
18415
+ const { lastname, color } = $randomItem(...LASTNAMES_WITH_COLORS);
18416
+ return {
18417
+ fullname: `${firstname} ${lastname}`,
18418
+ color,
18419
+ };
18420
+ }
18421
+ /**
18422
+ * TODO: [🤶] Maybe export through `@promptbook/utils` or `@promptbook/random` package
18423
+ */
18424
+
18425
+ const PERSONALITIES = [
18426
+ 'Friendly and helpful AI agent.',
18427
+ 'Professional and efficient virtual assistant.',
18428
+ 'Creative and imaginative digital companion.',
18429
+ 'Knowledgeable and informative AI guide.',
18430
+ 'Empathetic and understanding support bot.',
18431
+ 'Energetic and enthusiastic conversational partner.',
18432
+ 'Calm and patient virtual helper.',
18433
+ 'Curious and inquisitive AI explorer.',
18434
+ 'Witty and humorous digital friend.',
18435
+ 'Serious and focused AI consultant.',
18436
+ ];
18437
+ /**
18438
+ * @@@@
18439
+ *
18440
+ * @private internal helper function
18441
+ */
18442
+ function $randomAgentPersona() {
18443
+ return $randomItem(...PERSONALITIES);
18444
+ }
18445
+ /**
18446
+ * TODO: [🤶] Maybe export through `@promptbook/utils` or `@promptbook/random` package
18447
+ */
18448
+
18449
+ /**
18450
+ * Generates boilerplate for a new agent book
18451
+ *
18452
+ * Note: `$` is used to indicate that this function is not a pure function - it is not deterministic
18453
+ * Note: This function is using cryptographically secure components internally
18454
+ *
18455
+ * @public exported from `@promptbook/core`
18456
+ */
18457
+ function $generateBookBoilerplate(options) {
18458
+ // eslint-disable-next-line prefer-const
18459
+ let { agentName, parentAgentName = 'Adam', personaDescription, meta } = options || {};
18460
+ // eslint-disable-next-line prefer-const
18461
+ let { image, color, ...restMeta } = meta || {};
18462
+ if (!agentName) {
18463
+ const randomFullnameWithColor = $randomFullnameWithColor();
18464
+ agentName = randomFullnameWithColor.fullname;
18465
+ color = color || randomFullnameWithColor.color;
18466
+ }
18467
+ if (!personaDescription) {
18468
+ personaDescription = $randomAgentPersona();
18469
+ }
18470
+ const agentSource = validateBook(spaceTrim__default["default"]((block) => `
18471
+ ${agentName}
18472
+
18473
+ META COLOR ${color || '#3498db' /* <- TODO: !!!! Best default color */}
18474
+ PERSONA ${block(personaDescription)}
18475
+ `));
18476
+ return agentSource;
18477
+ }
18478
+ /**
18479
+ * TODO: [🤶] Maybe export through `@promptbook/utils` or `@promptbook/random` package
18480
+ */
18481
+
18150
18482
  exports.$bookTranspilersRegister = $bookTranspilersRegister;
18483
+ exports.$generateBookBoilerplate = $generateBookBoilerplate;
18151
18484
  exports.$llmToolsMetadataRegister = $llmToolsMetadataRegister;
18152
18485
  exports.$llmToolsRegister = $llmToolsRegister;
18153
18486
  exports.$scrapersMetadataRegister = $scrapersMetadataRegister;
@@ -18157,6 +18490,7 @@
18157
18490
  exports.API_REQUEST_TIMEOUT = API_REQUEST_TIMEOUT;
18158
18491
  exports.AbstractFormatError = AbstractFormatError;
18159
18492
  exports.Agent = Agent;
18493
+ exports.AgentCollectionInSupabase = AgentCollectionInSupabase;
18160
18494
  exports.AgentLlmExecutionTools = AgentLlmExecutionTools;
18161
18495
  exports.AuthenticationError = AuthenticationError;
18162
18496
  exports.BIG_DATASET_TRESHOLD = BIG_DATASET_TRESHOLD;
@@ -18195,6 +18529,7 @@
18195
18529
  exports.DEFAULT_SCRAPE_CACHE_DIRNAME = DEFAULT_SCRAPE_CACHE_DIRNAME;
18196
18530
  exports.DEFAULT_TASK_SIMULATED_DURATION_MS = DEFAULT_TASK_SIMULATED_DURATION_MS;
18197
18531
  exports.DEFAULT_TASK_TITLE = DEFAULT_TASK_TITLE;
18532
+ exports.DatabaseError = DatabaseError;
18198
18533
  exports.EXPECTATION_UNITS = EXPECTATION_UNITS;
18199
18534
  exports.EnvironmentMismatchError = EnvironmentMismatchError;
18200
18535
  exports.ExecutionReportStringOptionsDefaults = ExecutionReportStringOptionsDefaults;