@promptbook/cli 0.103.0-55 → 0.103.0-56

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 (61) hide show
  1. package/apps/agents-server/package-lock.json +1163 -0
  2. package/apps/agents-server/package.json +6 -0
  3. package/apps/agents-server/src/app/agents/[agentName]/AgentChatWrapper.tsx +3 -1
  4. package/apps/agents-server/src/app/agents/[agentName]/AgentOptionsMenu.tsx +216 -0
  5. package/apps/agents-server/src/app/agents/[agentName]/AgentProfileChat.tsx +78 -0
  6. package/apps/agents-server/src/app/agents/[agentName]/AgentProfileView.tsx +233 -0
  7. package/apps/agents-server/src/app/agents/[agentName]/CloneAgentButton.tsx +4 -4
  8. package/apps/agents-server/src/app/agents/[agentName]/InstallPwaButton.tsx +2 -2
  9. package/apps/agents-server/src/app/agents/[agentName]/QrCodeModal.tsx +90 -0
  10. package/apps/agents-server/src/app/agents/[agentName]/agentLinks.tsx +80 -0
  11. package/apps/agents-server/src/app/agents/[agentName]/api/book/route.ts +3 -1
  12. package/apps/agents-server/src/app/agents/[agentName]/api/chat/route.ts +11 -1
  13. package/apps/agents-server/src/app/agents/[agentName]/api/openai/models/route.ts +93 -0
  14. package/apps/agents-server/src/app/agents/[agentName]/api/openai/v1/chat/completions/route.ts +10 -0
  15. package/apps/agents-server/src/app/agents/[agentName]/api/openai/v1/models/route.ts +93 -0
  16. package/apps/agents-server/src/app/agents/[agentName]/api/voice/route.ts +4 -0
  17. package/apps/agents-server/src/app/agents/[agentName]/chat/page.tsx +9 -2
  18. package/apps/agents-server/src/app/agents/[agentName]/integration/SdkCodeTabs.tsx +31 -0
  19. package/apps/agents-server/src/app/agents/[agentName]/integration/page.tsx +271 -30
  20. package/apps/agents-server/src/app/agents/[agentName]/links/page.tsx +61 -97
  21. package/apps/agents-server/src/app/agents/[agentName]/page.tsx +108 -165
  22. package/apps/agents-server/src/app/agents/[agentName]/website-integration/page.tsx +61 -0
  23. package/apps/agents-server/src/app/api/openai/v1/chat/completions/route.ts +6 -0
  24. package/apps/agents-server/src/app/api/openai/v1/models/route.ts +65 -0
  25. package/apps/agents-server/src/app/docs/[docId]/page.tsx +12 -32
  26. package/apps/agents-server/src/app/docs/page.tsx +42 -17
  27. package/apps/agents-server/src/app/globals.css +129 -0
  28. package/apps/agents-server/src/app/layout.tsx +8 -2
  29. package/apps/agents-server/src/app/manifest.ts +1 -1
  30. package/apps/agents-server/src/components/DocumentationContent/DocumentationContent.tsx +87 -0
  31. package/apps/agents-server/src/components/OpenMojiIcon/OpenMojiIcon.tsx +20 -0
  32. package/apps/agents-server/src/components/PrintButton/PrintButton.tsx +18 -0
  33. package/apps/agents-server/src/components/PrintHeader/PrintHeader.tsx +18 -0
  34. package/apps/agents-server/src/database/migrations/2025-12-0070-chat-history-source.sql +2 -0
  35. package/apps/agents-server/src/database/schema.ts +6 -0
  36. package/apps/agents-server/src/utils/handleChatCompletion.ts +186 -14
  37. package/apps/agents-server/src/utils/resolveInheritedAgentSource.ts +13 -6
  38. package/apps/agents-server/src/utils/validateApiKey.ts +128 -0
  39. package/apps/agents-server/tailwind.config.ts +1 -1
  40. package/esm/index.es.js +865 -441
  41. package/esm/index.es.js.map +1 -1
  42. package/esm/typings/src/_packages/core.index.d.ts +6 -8
  43. package/esm/typings/src/_packages/types.index.d.ts +1 -1
  44. package/esm/typings/src/book-components/Chat/LlmChat/LlmChatProps.d.ts +5 -0
  45. package/esm/typings/src/commitments/META_COLOR/META_COLOR.d.ts +6 -0
  46. package/esm/typings/src/commitments/META_FONT/META_FONT.d.ts +42 -0
  47. package/esm/typings/src/commitments/USE/USE.d.ts +53 -0
  48. package/esm/typings/src/commitments/USE_BROWSER/USE_BROWSER.d.ts +38 -0
  49. package/esm/typings/src/commitments/USE_BROWSER/USE_BROWSER.test.d.ts +1 -0
  50. package/esm/typings/src/commitments/{IMPORTANT/IMPORTANT.d.ts → USE_MCP/USE_MCP.d.ts} +16 -5
  51. package/esm/typings/src/commitments/USE_SEARCH_ENGINE/USE_SEARCH_ENGINE.d.ts +38 -0
  52. package/esm/typings/src/commitments/index.d.ts +93 -1
  53. package/esm/typings/src/playground/playground.d.ts +3 -0
  54. package/esm/typings/src/utils/color/Color.d.ts +8 -0
  55. package/esm/typings/src/utils/color/css-colors.d.ts +1 -0
  56. package/esm/typings/src/version.d.ts +1 -1
  57. package/package.json +1 -1
  58. package/umd/index.umd.js +861 -437
  59. package/umd/index.umd.js.map +1 -1
  60. package/esm/typings/src/commitments/registry.d.ts +0 -68
  61. package/esm/typings/src/playground/playground1.d.ts +0 -2
package/umd/index.umd.js CHANGED
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
2
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('commander'), require('spacetrim'), require('waitasecond'), require('prompts'), require('path'), require('fs/promises'), require('dotenv'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('crypto'), require('socket.io-client'), require('rxjs'), require('child_process'), require('jszip'), require('papaparse'), require('crypto-js'), require('mime-types'), require('glob-promise'), require('moment'), require('express'), require('express-openapi-validator'), require('http'), require('socket.io'), require('swagger-ui-express'), require('react'), require('react-dom/server'), require('@anthropic-ai/sdk'), require('bottleneck'), require('@azure/openai'), require('openai'), require('@mozilla/readability'), require('jsdom'), require('showdown')) :
3
3
  typeof define === 'function' && define.amd ? define(['exports', 'colors', 'commander', 'spacetrim', 'waitasecond', 'prompts', 'path', 'fs/promises', 'dotenv', 'crypto-js/enc-hex', 'crypto-js/sha256', 'crypto', 'socket.io-client', 'rxjs', 'child_process', 'jszip', 'papaparse', 'crypto-js', 'mime-types', 'glob-promise', 'moment', 'express', 'express-openapi-validator', 'http', 'socket.io', 'swagger-ui-express', 'react', 'react-dom/server', '@anthropic-ai/sdk', 'bottleneck', '@azure/openai', 'openai', '@mozilla/readability', 'jsdom', 'showdown'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.colors, global.commander, global.spaceTrim, global.waitasecond, global.prompts, global.path, global.promises, global.dotenv, global.hexEncoder, global.sha256, global.crypto, global.socket_ioClient, global.rxjs, global.child_process, global.JSZip, global.papaparse, global.cryptoJs, global.mimeTypes, global.glob, global.moment, global.express, global.OpenApiValidator, global.http, global.socket_io, global.swaggerUi, global.react, global.server, global.Anthropic, global.Bottleneck, global.openai, global.OpenAI, global.readability, global.jsdom, global.showdown));
5
- })(this, (function (exports, colors, commander, spaceTrim, waitasecond, prompts, path, promises, dotenv, hexEncoder, sha256, crypto, socket_ioClient, rxjs, child_process, JSZip, papaparse, cryptoJs, mimeTypes, glob, moment, express, OpenApiValidator, http, socket_io, swaggerUi, react, server, Anthropic, Bottleneck, openai, OpenAI, readability, jsdom, showdown) { 'use strict';
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.colors, global.commander, global.spaceTrim$1, global.waitasecond, global.prompts, global.path, global.promises, global.dotenv, global.hexEncoder, global.sha256, global.crypto, global.socket_ioClient, global.rxjs, global.child_process, global.JSZip, global.papaparse, global.cryptoJs, global.mimeTypes, global.glob, global.moment, global.express, global.OpenApiValidator, global.http, global.socket_io, global.swaggerUi, global.react, global.server, global.Anthropic, global.Bottleneck, global.openai, global.OpenAI, global.readability, global.jsdom, global.showdown));
5
+ })(this, (function (exports, colors, commander, spaceTrim$1, waitasecond, prompts, path, promises, dotenv, hexEncoder, sha256, crypto, socket_ioClient, rxjs, child_process, JSZip, papaparse, cryptoJs, mimeTypes, glob, moment, express, OpenApiValidator, http, socket_io, swaggerUi, react, server, Anthropic, Bottleneck, openai, OpenAI, readability, jsdom, showdown) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
@@ -26,7 +26,7 @@
26
26
 
27
27
  var colors__default = /*#__PURE__*/_interopDefaultLegacy(colors);
28
28
  var commander__default = /*#__PURE__*/_interopDefaultLegacy(commander);
29
- var spaceTrim__default = /*#__PURE__*/_interopDefaultLegacy(spaceTrim);
29
+ var spaceTrim__default = /*#__PURE__*/_interopDefaultLegacy(spaceTrim$1);
30
30
  var prompts__default = /*#__PURE__*/_interopDefaultLegacy(prompts);
31
31
  var dotenv__namespace = /*#__PURE__*/_interopNamespace(dotenv);
32
32
  var hexEncoder__default = /*#__PURE__*/_interopDefaultLegacy(hexEncoder);
@@ -56,7 +56,7 @@
56
56
  * @generated
57
57
  * @see https://github.com/webgptorg/promptbook
58
58
  */
59
- const PROMPTBOOK_ENGINE_VERSION = '0.103.0-55';
59
+ const PROMPTBOOK_ENGINE_VERSION = '0.103.0-56';
60
60
  /**
61
61
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
62
62
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -110,6 +110,17 @@
110
110
  * Note: [💞] Ignore a discrepancy between file name and entity name
111
111
  */
112
112
 
113
+ /**
114
+ * Trims string from all 4 sides
115
+ *
116
+ * Note: This is a re-exported function from the `spacetrim` package which is
117
+ * Developed by same author @hejny as this package
118
+ *
119
+ * @public exported from `@promptbook/utils`
120
+ * @see https://github.com/hejny/spacetrim#usage
121
+ */
122
+ const spaceTrim = spaceTrim$1.spaceTrim;
123
+
113
124
  /**
114
125
  * Just marks a place of place where should be something implemented
115
126
  * No side effects.
@@ -171,6 +182,7 @@
171
182
  * @public exported from `@promptbook/color`
172
183
  */
173
184
  const CSS_COLORS = {
185
+ promptbook: '#79EAFD',
174
186
  transparent: 'rgba(0,0,0,0)',
175
187
  aliceblue: '#f0f8ff',
176
188
  antiquewhite: '#faebd7',
@@ -386,6 +398,28 @@
386
398
  throw new Error(`Can not create color from given object`);
387
399
  }
388
400
  }
401
+ /**
402
+ * Creates a new Color instance from miscellaneous formats
403
+ * It just does not throw error when it fails, it returns PROMPTBOOK_COLOR instead
404
+ *
405
+ * @param color
406
+ * @returns Color object
407
+ */
408
+ static fromSafe(color) {
409
+ try {
410
+ return Color.from(color);
411
+ }
412
+ catch (error) {
413
+ // <- Note: Can not use `assertsError(error)` here because it causes circular dependency
414
+ console.warn(spaceTrim((block) => `
415
+ Color.fromSafe error:
416
+ ${block(error.message)}
417
+
418
+ Returning default PROMPTBOOK_COLOR.
419
+ `));
420
+ return Color.fromString('promptbook');
421
+ }
422
+ }
389
423
  /**
390
424
  * Creates a new Color instance from miscellaneous string formats
391
425
  *
@@ -1009,7 +1043,7 @@
1009
1043
  *
1010
1044
  * @public exported from `@promptbook/core`
1011
1045
  */
1012
- const PROMPTBOOK_COLOR = Color.fromHex('#79EAFD');
1046
+ const PROMPTBOOK_COLOR = Color.fromString('promptbook');
1013
1047
  // <- TODO: [🧠][🈵] Using `Color` here increases the package size approx 3kb, maybe remove it
1014
1048
  /**
1015
1049
  * Colors for syntax highlighting in the `<BookEditor/>`
@@ -1450,7 +1484,7 @@
1450
1484
  */
1451
1485
  class UnexpectedError extends Error {
1452
1486
  constructor(message) {
1453
- super(spaceTrim.spaceTrim((block) => `
1487
+ super(spaceTrim$1.spaceTrim((block) => `
1454
1488
  ${block(message)}
1455
1489
 
1456
1490
  Note: This error should not happen.
@@ -1476,7 +1510,7 @@
1476
1510
  constructor(whatWasThrown) {
1477
1511
  const tag = `[🤮]`;
1478
1512
  console.error(tag, whatWasThrown);
1479
- super(spaceTrim.spaceTrim(`
1513
+ super(spaceTrim$1.spaceTrim(`
1480
1514
  Non-Error object was thrown
1481
1515
 
1482
1516
  Note: Look for ${tag} in the console for more details
@@ -1621,7 +1655,7 @@
1621
1655
  */
1622
1656
  class NotYetImplementedError extends Error {
1623
1657
  constructor(message) {
1624
- super(spaceTrim.spaceTrim((block) => `
1658
+ super(spaceTrim$1.spaceTrim((block) => `
1625
1659
  ${block(message)}
1626
1660
 
1627
1661
  Note: This feature is not implemented yet but it will be soon.
@@ -3295,7 +3329,7 @@
3295
3329
  */
3296
3330
  class MissingToolsError extends Error {
3297
3331
  constructor(message) {
3298
- super(spaceTrim.spaceTrim((block) => `
3332
+ super(spaceTrim$1.spaceTrim((block) => `
3299
3333
  ${block(message)}
3300
3334
 
3301
3335
  Note: You have probably forgot to provide some tools for pipeline execution or preparation
@@ -4013,7 +4047,7 @@
4013
4047
  }
4014
4048
  catch (error) {
4015
4049
  keepUnused(error);
4016
- throw new ExpectError(spaceTrim.spaceTrim((block) => `
4050
+ throw new ExpectError(spaceTrim$1.spaceTrim((block) => `
4017
4051
  Expected valid JSON string
4018
4052
 
4019
4053
  The expected JSON text:
@@ -5226,11 +5260,11 @@
5226
5260
  console.warn(`Command "${humanReadableCommand}" exited with code ${code}`);
5227
5261
  // <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
5228
5262
  }
5229
- resolve(spaceTrim.spaceTrim(output.join('\n')));
5263
+ resolve(spaceTrim$1.spaceTrim(output.join('\n')));
5230
5264
  }
5231
5265
  }
5232
5266
  else {
5233
- resolve(spaceTrim.spaceTrim(output.join('\n')));
5267
+ resolve(spaceTrim$1.spaceTrim(output.join('\n')));
5234
5268
  }
5235
5269
  };
5236
5270
  commandProcess.on('close', finishWithCode);
@@ -5248,7 +5282,7 @@
5248
5282
  console.warn(error);
5249
5283
  // <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
5250
5284
  }
5251
- resolve(spaceTrim.spaceTrim(output.join('\n')));
5285
+ resolve(spaceTrim$1.spaceTrim(output.join('\n')));
5252
5286
  }
5253
5287
  });
5254
5288
  }
@@ -5780,7 +5814,7 @@
5780
5814
  if (!(error instanceof PipelineLogicError)) {
5781
5815
  throw error;
5782
5816
  }
5783
- console.error(spaceTrim.spaceTrim((block) => `
5817
+ console.error(spaceTrim$1.spaceTrim((block) => `
5784
5818
  Pipeline is not valid but logic errors are temporarily disabled via \`IS_PIPELINE_LOGIC_VALIDATED\`
5785
5819
 
5786
5820
  ${block(error.message)}
@@ -5807,7 +5841,7 @@
5807
5841
  })();
5808
5842
  if (pipeline.pipelineUrl !== undefined && !isValidPipelineUrl(pipeline.pipelineUrl)) {
5809
5843
  // <- Note: [🚲]
5810
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
5844
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
5811
5845
  Invalid promptbook URL "${pipeline.pipelineUrl}"
5812
5846
 
5813
5847
  ${block(pipelineIdentification)}
@@ -5815,7 +5849,7 @@
5815
5849
  }
5816
5850
  if (pipeline.bookVersion !== undefined && !isValidPromptbookVersion(pipeline.bookVersion)) {
5817
5851
  // <- Note: [🚲]
5818
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
5852
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
5819
5853
  Invalid Promptbook Version "${pipeline.bookVersion}"
5820
5854
 
5821
5855
  ${block(pipelineIdentification)}
@@ -5824,7 +5858,7 @@
5824
5858
  // TODO: [🧠] Maybe do here some proper JSON-schema / ZOD checking
5825
5859
  if (!Array.isArray(pipeline.parameters)) {
5826
5860
  // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
5827
- throw new ParseError(spaceTrim.spaceTrim((block) => `
5861
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
5828
5862
  Pipeline is valid JSON but with wrong structure
5829
5863
 
5830
5864
  \`PipelineJson.parameters\` expected to be an array, but got ${typeof pipeline.parameters}
@@ -5835,7 +5869,7 @@
5835
5869
  // TODO: [🧠] Maybe do here some proper JSON-schema / ZOD checking
5836
5870
  if (!Array.isArray(pipeline.tasks)) {
5837
5871
  // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
5838
- throw new ParseError(spaceTrim.spaceTrim((block) => `
5872
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
5839
5873
  Pipeline is valid JSON but with wrong structure
5840
5874
 
5841
5875
  \`PipelineJson.tasks\` expected to be an array, but got ${typeof pipeline.tasks}
@@ -5861,7 +5895,7 @@
5861
5895
  // Note: Check each parameter individually
5862
5896
  for (const parameter of pipeline.parameters) {
5863
5897
  if (parameter.isInput && parameter.isOutput) {
5864
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
5898
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
5865
5899
 
5866
5900
  Parameter \`{${parameter.name}}\` can not be both input and output
5867
5901
 
@@ -5872,7 +5906,7 @@
5872
5906
  if (!parameter.isInput &&
5873
5907
  !parameter.isOutput &&
5874
5908
  !pipeline.tasks.some((task) => task.dependentParameterNames.includes(parameter.name))) {
5875
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
5909
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
5876
5910
  Parameter \`{${parameter.name}}\` is created but not used
5877
5911
 
5878
5912
  You can declare {${parameter.name}} as output parameter by adding in the header:
@@ -5884,7 +5918,7 @@
5884
5918
  }
5885
5919
  // Note: Testing that parameter is either input or result of some task
5886
5920
  if (!parameter.isInput && !pipeline.tasks.some((task) => task.resultingParameterName === parameter.name)) {
5887
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
5921
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
5888
5922
  Parameter \`{${parameter.name}}\` is declared but not defined
5889
5923
 
5890
5924
  You can do one of these:
@@ -5900,14 +5934,14 @@
5900
5934
  // Note: Checking each task individually
5901
5935
  for (const task of pipeline.tasks) {
5902
5936
  if (definedParameters.has(task.resultingParameterName)) {
5903
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
5937
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
5904
5938
  Parameter \`{${task.resultingParameterName}}\` is defined multiple times
5905
5939
 
5906
5940
  ${block(pipelineIdentification)}
5907
5941
  `));
5908
5942
  }
5909
5943
  if (RESERVED_PARAMETER_NAMES.includes(task.resultingParameterName)) {
5910
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
5944
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
5911
5945
  Parameter name {${task.resultingParameterName}} is reserved, please use different name
5912
5946
 
5913
5947
  ${block(pipelineIdentification)}
@@ -5917,7 +5951,7 @@
5917
5951
  if (task.jokerParameterNames && task.jokerParameterNames.length > 0) {
5918
5952
  if (!task.format &&
5919
5953
  !task.expectations /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
5920
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
5954
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
5921
5955
  Joker parameters are used for {${task.resultingParameterName}} but no expectations are defined
5922
5956
 
5923
5957
  ${block(pipelineIdentification)}
@@ -5925,7 +5959,7 @@
5925
5959
  }
5926
5960
  for (const joker of task.jokerParameterNames) {
5927
5961
  if (!task.dependentParameterNames.includes(joker)) {
5928
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
5962
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
5929
5963
  Parameter \`{${joker}}\` is used for {${task.resultingParameterName}} as joker but not in \`dependentParameterNames\`
5930
5964
 
5931
5965
  ${block(pipelineIdentification)}
@@ -5936,21 +5970,21 @@
5936
5970
  if (task.expectations) {
5937
5971
  for (const [unit, { min, max }] of Object.entries(task.expectations)) {
5938
5972
  if (min !== undefined && max !== undefined && min > max) {
5939
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
5973
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
5940
5974
  Min expectation (=${min}) of ${unit} is higher than max expectation (=${max})
5941
5975
 
5942
5976
  ${block(pipelineIdentification)}
5943
5977
  `));
5944
5978
  }
5945
5979
  if (min !== undefined && min < 0) {
5946
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
5980
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
5947
5981
  Min expectation of ${unit} must be zero or positive
5948
5982
 
5949
5983
  ${block(pipelineIdentification)}
5950
5984
  `));
5951
5985
  }
5952
5986
  if (max !== undefined && max <= 0) {
5953
- throw new PipelineLogicError(spaceTrim.spaceTrim((block) => `
5987
+ throw new PipelineLogicError(spaceTrim$1.spaceTrim((block) => `
5954
5988
  Max expectation of ${unit} must be positive
5955
5989
 
5956
5990
  ${block(pipelineIdentification)}
@@ -5972,7 +6006,7 @@
5972
6006
  while (unresovedTasks.length > 0) {
5973
6007
  if (loopLimit-- < 0) {
5974
6008
  // Note: Really UnexpectedError not LimitReachedError - this should not happen and be caught below
5975
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
6009
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
5976
6010
  Loop limit reached during detection of circular dependencies in \`validatePipeline\`
5977
6011
 
5978
6012
  ${block(pipelineIdentification)}
@@ -5982,7 +6016,7 @@
5982
6016
  if (currentlyResovedTasks.length === 0) {
5983
6017
  throw new PipelineLogicError(
5984
6018
  // TODO: [🐎] DRY
5985
- spaceTrim.spaceTrim((block) => `
6019
+ spaceTrim$1.spaceTrim((block) => `
5986
6020
 
5987
6021
  Can not resolve some parameters:
5988
6022
  Either you are using a parameter that is not defined, or there are some circular dependencies.
@@ -6317,7 +6351,7 @@
6317
6351
  for (const pipeline of pipelines) {
6318
6352
  // TODO: [👠] DRY
6319
6353
  if (pipeline.pipelineUrl === undefined) {
6320
- throw new PipelineUrlError(spaceTrim.spaceTrim(`
6354
+ throw new PipelineUrlError(spaceTrim$1.spaceTrim(`
6321
6355
  Pipeline with name "${pipeline.title}" does not have defined URL
6322
6356
 
6323
6357
  File:
@@ -6339,7 +6373,7 @@
6339
6373
  pipelineJsonToString(unpreparePipeline(pipeline)) !==
6340
6374
  pipelineJsonToString(unpreparePipeline(this.collection.get(pipeline.pipelineUrl)))) {
6341
6375
  const existing = this.collection.get(pipeline.pipelineUrl);
6342
- throw new PipelineUrlError(spaceTrim.spaceTrim(`
6376
+ throw new PipelineUrlError(spaceTrim$1.spaceTrim(`
6343
6377
  Pipeline with URL ${pipeline.pipelineUrl} is already in the collection 🍎
6344
6378
 
6345
6379
  Conflicting files:
@@ -6371,13 +6405,13 @@
6371
6405
  const pipeline = this.collection.get(url);
6372
6406
  if (!pipeline) {
6373
6407
  if (this.listPipelines().length === 0) {
6374
- throw new NotFoundError(spaceTrim.spaceTrim(`
6408
+ throw new NotFoundError(spaceTrim$1.spaceTrim(`
6375
6409
  Pipeline with url "${url}" not found
6376
6410
 
6377
6411
  No pipelines available
6378
6412
  `));
6379
6413
  }
6380
- throw new NotFoundError(spaceTrim.spaceTrim((block) => `
6414
+ throw new NotFoundError(spaceTrim$1.spaceTrim((block) => `
6381
6415
  Pipeline with url "${url}" not found
6382
6416
 
6383
6417
  Available pipelines:
@@ -6535,11 +6569,11 @@
6535
6569
  throw deserializeError(errors[0]);
6536
6570
  }
6537
6571
  else {
6538
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
6572
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
6539
6573
  Multiple errors occurred during Promptbook execution
6540
6574
 
6541
6575
  ${block(errors
6542
- .map(({ name, stack, message }, index) => spaceTrim.spaceTrim((block) => `
6576
+ .map(({ name, stack, message }, index) => spaceTrim$1.spaceTrim((block) => `
6543
6577
  ${name} ${index + 1}:
6544
6578
  ${block(stack || message)}
6545
6579
  `))
@@ -6878,7 +6912,7 @@
6878
6912
  }
6879
6913
  catch (error) {
6880
6914
  assertsError(error);
6881
- throw new ParseError(spaceTrim.spaceTrim((block) => `
6915
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
6882
6916
  Can not extract variables from the script
6883
6917
  ${block(error.stack || error.message)}
6884
6918
 
@@ -7478,7 +7512,7 @@
7478
7512
  const jokerParameterName = jokerParameterNames[jokerParameterNames.length + attemptIndex];
7479
7513
  // TODO: [🧠][🍭] JOKERS, EXPECTATIONS, POSTPROCESSING and FOREACH
7480
7514
  if (isJokerAttempt && !jokerParameterName) {
7481
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
7515
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
7482
7516
  Joker not found in attempt ${attemptIndex}
7483
7517
 
7484
7518
  ${block(pipelineIdentification)}
@@ -7489,7 +7523,7 @@
7489
7523
  $ongoingTaskResult.$expectError = null;
7490
7524
  if (isJokerAttempt) {
7491
7525
  if (parameters[jokerParameterName] === undefined) {
7492
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
7526
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
7493
7527
  Joker parameter {${jokerParameterName}} not defined
7494
7528
 
7495
7529
  ${block(pipelineIdentification)}
@@ -7547,7 +7581,7 @@
7547
7581
  $ongoingTaskResult.$resultString = $ongoingTaskResult.$completionResult.content;
7548
7582
  break variant;
7549
7583
  case 'EMBEDDING':
7550
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
7584
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
7551
7585
  Embedding model can not be used in pipeline
7552
7586
 
7553
7587
  This should be catched during parsing
@@ -7558,7 +7592,7 @@
7558
7592
  break variant;
7559
7593
  // <- case [🤖]:
7560
7594
  default:
7561
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
7595
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
7562
7596
  Unknown model variant "${task.modelRequirements.modelVariant}"
7563
7597
 
7564
7598
  ${block(pipelineIdentification)}
@@ -7569,14 +7603,14 @@
7569
7603
  break;
7570
7604
  case 'SCRIPT_TASK':
7571
7605
  if (arrayableToArray(tools.script).length === 0) {
7572
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
7606
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
7573
7607
  No script execution tools are available
7574
7608
 
7575
7609
  ${block(pipelineIdentification)}
7576
7610
  `));
7577
7611
  }
7578
7612
  if (!task.contentLanguage) {
7579
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
7613
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
7580
7614
  Script language is not defined for SCRIPT TASK "${task.name}"
7581
7615
 
7582
7616
  ${block(pipelineIdentification)}
@@ -7607,7 +7641,7 @@
7607
7641
  throw $ongoingTaskResult.$scriptPipelineExecutionErrors[0];
7608
7642
  }
7609
7643
  else {
7610
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
7644
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
7611
7645
  Script execution failed ${$ongoingTaskResult.$scriptPipelineExecutionErrors.length}x
7612
7646
 
7613
7647
  ${block(pipelineIdentification)}
@@ -7621,7 +7655,7 @@
7621
7655
  break taskType;
7622
7656
  case 'DIALOG_TASK':
7623
7657
  if (tools.userInterface === undefined) {
7624
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
7658
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
7625
7659
  User interface tools are not available
7626
7660
 
7627
7661
  ${block(pipelineIdentification)}
@@ -7639,7 +7673,7 @@
7639
7673
  break taskType;
7640
7674
  // <- case: [🅱]
7641
7675
  default:
7642
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
7676
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
7643
7677
  Unknown execution type "${task.taskType}"
7644
7678
 
7645
7679
  ${block(pipelineIdentification)}
@@ -7737,7 +7771,7 @@
7737
7771
  if ($ongoingTaskResult.$expectError !== null && attemptIndex === maxAttempts - 1) {
7738
7772
  // Note: Create a summary of all failures
7739
7773
  const failuresSummary = $ongoingTaskResult.$failedResults
7740
- .map((failure) => spaceTrim.spaceTrim((block) => {
7774
+ .map((failure) => spaceTrim$1.spaceTrim((block) => {
7741
7775
  var _a, _b;
7742
7776
  return `
7743
7777
  Attempt ${failure.attemptIndex + 1}:
@@ -7747,14 +7781,14 @@
7747
7781
  Result:
7748
7782
  ${block(failure.result === null
7749
7783
  ? 'null'
7750
- : spaceTrim.spaceTrim(failure.result)
7784
+ : spaceTrim$1.spaceTrim(failure.result)
7751
7785
  .split('\n')
7752
7786
  .map((line) => `> ${line}`)
7753
7787
  .join('\n'))}
7754
7788
  `;
7755
7789
  }))
7756
7790
  .join('\n\n---\n\n');
7757
- throw new PipelineExecutionError(spaceTrim.spaceTrim((block) => {
7791
+ throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => {
7758
7792
  var _a;
7759
7793
  return `
7760
7794
  LLM execution failed ${maxExecutionAttempts}x
@@ -7774,7 +7808,7 @@
7774
7808
  }
7775
7809
  }
7776
7810
  if ($ongoingTaskResult.$resultString === null) {
7777
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
7811
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
7778
7812
  Something went wrong and prompt result is null
7779
7813
 
7780
7814
  ${block(pipelineIdentification)}
@@ -8080,7 +8114,7 @@
8080
8114
  // Note: Doublecheck that ALL reserved parameters are defined:
8081
8115
  for (const parameterName of RESERVED_PARAMETER_NAMES) {
8082
8116
  if (reservedParameters[parameterName] === undefined) {
8083
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
8117
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
8084
8118
  Reserved parameter {${parameterName}} is not defined
8085
8119
 
8086
8120
  ${block(pipelineIdentification)}
@@ -8106,7 +8140,7 @@
8106
8140
  const dependentParameterNames = new Set(currentTask.dependentParameterNames);
8107
8141
  // TODO: [👩🏾‍🤝‍👩🏻] Use here `mapAvailableToExpectedParameters`
8108
8142
  if (difference(union(difference(usedParameterNames, dependentParameterNames), difference(dependentParameterNames, usedParameterNames)), new Set(RESERVED_PARAMETER_NAMES)).size !== 0) {
8109
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
8143
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
8110
8144
  Dependent parameters are not consistent with used parameters:
8111
8145
 
8112
8146
  Dependent parameters:
@@ -8150,7 +8184,7 @@
8150
8184
  else if (!definedParameterNames.has(parameterName) && usedParameterNames.has(parameterName)) {
8151
8185
  // Houston, we have a problem
8152
8186
  // Note: Checking part is also done in `validatePipeline`, but it’s good to doublecheck
8153
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
8187
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
8154
8188
  Parameter \`{${parameterName}}\` is NOT defined
8155
8189
  BUT used in task "${currentTask.title || currentTask.name}"
8156
8190
 
@@ -8219,7 +8253,7 @@
8219
8253
  for (const parameter of preparedPipeline.parameters.filter(({ isOutput }) => isOutput)) {
8220
8254
  if (parametersToPass[parameter.name] === undefined) {
8221
8255
  // [4]
8222
- $warnings.push(new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
8256
+ $warnings.push(new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
8223
8257
  Parameter \`{${parameter.name}}\` should be an output parameter, but it was not generated during pipeline execution
8224
8258
 
8225
8259
  Note: This is a warning which happened after the pipeline was executed, and \`{${parameter.name}}\` was not for some reason defined in output parameters
@@ -8327,7 +8361,7 @@
8327
8361
  for (const parameterName of Object.keys(inputParameters)) {
8328
8362
  const parameter = preparedPipeline.parameters.find(({ name }) => name === parameterName);
8329
8363
  if (parameter === undefined) {
8330
- warnings.push(new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
8364
+ warnings.push(new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
8331
8365
  Extra parameter {${parameterName}} is being passed which is not part of the pipeline.
8332
8366
 
8333
8367
  ${block(pipelineIdentification)}
@@ -8342,7 +8376,7 @@
8342
8376
  // TODO: [🧠] This should be also non-critical error
8343
8377
  return exportJson({
8344
8378
  name: 'pipelineExecutorResult',
8345
- message: spaceTrim.spaceTrim((block) => `
8379
+ message: spaceTrim$1.spaceTrim((block) => `
8346
8380
  Unsuccessful PipelineExecutorResult (with extra parameter {${parameter.name}}) PipelineExecutorResult
8347
8381
 
8348
8382
  ${block(pipelineIdentification)}
@@ -8351,7 +8385,7 @@
8351
8385
  value: {
8352
8386
  isSuccessful: false,
8353
8387
  errors: [
8354
- new PipelineExecutionError(spaceTrim.spaceTrim((block) => `
8388
+ new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
8355
8389
  Parameter \`{${parameter.name}}\` is passed as input parameter but it is not input
8356
8390
 
8357
8391
  ${block(pipelineIdentification)}
@@ -8378,7 +8412,7 @@
8378
8412
  while (unresovedTasks.length > 0) {
8379
8413
  if (loopLimit-- < 0) {
8380
8414
  // Note: Really UnexpectedError not LimitReachedError - this should be catched during validatePipeline
8381
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
8415
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
8382
8416
  Loop limit reached during resolving parameters pipeline execution
8383
8417
 
8384
8418
  ${block(pipelineIdentification)}
@@ -8388,7 +8422,7 @@
8388
8422
  if (!currentTask && resolving.length === 0) {
8389
8423
  throw new UnexpectedError(
8390
8424
  // TODO: [🐎] DRY
8391
- spaceTrim.spaceTrim((block) => `
8425
+ spaceTrim$1.spaceTrim((block) => `
8392
8426
  Can not resolve some parameters:
8393
8427
 
8394
8428
  ${block(pipelineIdentification)}
@@ -8428,7 +8462,7 @@
8428
8462
  tools,
8429
8463
  onProgress(newOngoingResult) {
8430
8464
  if (isReturned) {
8431
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
8465
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
8432
8466
  Can not call \`onProgress\` after pipeline execution is finished
8433
8467
 
8434
8468
  ${block(pipelineIdentification)}
@@ -8445,7 +8479,7 @@
8445
8479
  },
8446
8480
  logLlmCall,
8447
8481
  $executionReport: executionReport,
8448
- pipelineIdentification: spaceTrim.spaceTrim((block) => `
8482
+ pipelineIdentification: spaceTrim$1.spaceTrim((block) => `
8449
8483
  ${block(pipelineIdentification)}
8450
8484
  Task name: ${currentTask.name}
8451
8485
  Task title: ${currentTask.title}
@@ -8554,7 +8588,7 @@
8554
8588
  preparedPipeline = pipeline;
8555
8589
  }
8556
8590
  else if (isNotPreparedWarningSuppressed !== true) {
8557
- console.warn(spaceTrim.spaceTrim((block) => `
8591
+ console.warn(spaceTrim$1.spaceTrim((block) => `
8558
8592
  Pipeline is not prepared
8559
8593
 
8560
8594
  ${block(pipelineIdentification)}
@@ -8579,7 +8613,7 @@
8579
8613
  tools,
8580
8614
  onProgress,
8581
8615
  logLlmCall,
8582
- pipelineIdentification: spaceTrim.spaceTrim((block) => `
8616
+ pipelineIdentification: spaceTrim$1.spaceTrim((block) => `
8583
8617
  ${block(pipelineIdentification)}
8584
8618
  ${runCount === 1 ? '' : `Run #${runCount}`}
8585
8619
  `),
@@ -9166,7 +9200,7 @@
9166
9200
  if (task.taskType === 'PROMPT_TASK' &&
9167
9201
  knowledgePiecesCount > 0 &&
9168
9202
  !dependentParameterNames.includes('knowledge')) {
9169
- preparedContent = spaceTrim.spaceTrim(`
9203
+ preparedContent = spaceTrim$1.spaceTrim(`
9170
9204
  {content}
9171
9205
 
9172
9206
  ## Knowledge
@@ -11683,7 +11717,7 @@
11683
11717
  function getParserForCommand(command) {
11684
11718
  const commandParser = COMMANDS.find((commandParser) => commandParser.name === command.type);
11685
11719
  if (commandParser === undefined) {
11686
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
11720
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
11687
11721
  Command ${command.type} parser is not found
11688
11722
 
11689
11723
  ${block(JSON.stringify(command, null, 4)
@@ -11759,7 +11793,7 @@
11759
11793
  .map(removeMarkdownFormatting)
11760
11794
  .map((item) => item.trim());
11761
11795
  if (items.length === 0 || items[0] === '') {
11762
- throw new ParseError(spaceTrim.spaceTrim((block) => `
11796
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
11763
11797
  Malformed command:
11764
11798
  - ${raw}
11765
11799
 
@@ -11795,7 +11829,7 @@
11795
11829
  return command;
11796
11830
  }
11797
11831
  }
11798
- throw new ParseError(spaceTrim.spaceTrim((block) => `
11832
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
11799
11833
  Malformed or unknown command:
11800
11834
  - ${raw}
11801
11835
 
@@ -11846,7 +11880,7 @@
11846
11880
  if (!(error instanceof ParseError)) {
11847
11881
  throw error;
11848
11882
  }
11849
- throw new ParseError(spaceTrim.spaceTrim((block) => `
11883
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
11850
11884
  Invalid ${commandName} command:
11851
11885
 
11852
11886
  Your command:
@@ -12162,7 +12196,7 @@
12162
12196
  * @public exported from `@promptbook/markdown-utils`
12163
12197
  */
12164
12198
  function removeMarkdownComments(content) {
12165
- return spaceTrim.spaceTrim(content.replace(/<!--(.*?)-->/gs, ''));
12199
+ return spaceTrim$1.spaceTrim(content.replace(/<!--(.*?)-->/gs, ''));
12166
12200
  }
12167
12201
 
12168
12202
  /**
@@ -12478,7 +12512,7 @@
12478
12512
  if (pipelineString.startsWith('#!')) {
12479
12513
  const [shebangLine, ...restLines] = pipelineString.split('\n');
12480
12514
  if (!(shebangLine || '').includes('ptbk')) {
12481
- throw new ParseError(spaceTrim.spaceTrim((block) => `
12515
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
12482
12516
  It seems that you try to parse a book file which has non-standard shebang line for book files:
12483
12517
  Shebang line must contain 'ptbk'
12484
12518
 
@@ -12494,7 +12528,7 @@
12494
12528
  pipelineString = validatePipelineString(restLines.join('\n'));
12495
12529
  }
12496
12530
  pipelineString = removeMarkdownComments(pipelineString);
12497
- pipelineString = spaceTrim.spaceTrim(pipelineString);
12531
+ pipelineString = spaceTrim$1.spaceTrim(pipelineString);
12498
12532
  // <- TODO: [😧] `spaceTrim` should preserve discriminated type *(or at lease `PipelineString`)*
12499
12533
  pipelineString = deflatePipeline(pipelineString);
12500
12534
  // ==============
@@ -12506,7 +12540,7 @@
12506
12540
  // ==============
12507
12541
  // Note: 1️⃣◽4️⃣ Check markdown structure
12508
12542
  if (pipelineHead === undefined) {
12509
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
12543
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
12510
12544
  Pipeline head is not defined
12511
12545
 
12512
12546
  ${block(getPipelineIdentification())}
@@ -12515,7 +12549,7 @@
12515
12549
  `));
12516
12550
  }
12517
12551
  if (pipelineHead.level !== 1) {
12518
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
12552
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
12519
12553
  Pipeline head is not h1
12520
12554
 
12521
12555
  ${block(getPipelineIdentification())}
@@ -12524,7 +12558,7 @@
12524
12558
  `));
12525
12559
  }
12526
12560
  if (!pipelineSections.every((section) => section.level === 2)) {
12527
- throw new UnexpectedError(spaceTrim.spaceTrim((block) => `
12561
+ throw new UnexpectedError(spaceTrim$1.spaceTrim((block) => `
12528
12562
  Not every pipeline section is h2
12529
12563
 
12530
12564
  ${block(getPipelineIdentification())}
@@ -12537,7 +12571,7 @@
12537
12571
  const defineParam = (parameterCommand) => {
12538
12572
  const { parameterName, parameterDescription, isInput, isOutput } = parameterCommand;
12539
12573
  if (RESERVED_PARAMETER_NAMES.includes(parameterName)) {
12540
- throw new ParseError(spaceTrim.spaceTrim((block) => `
12574
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
12541
12575
  Parameter name {${parameterName}} is reserved and cannot be used as resulting parameter name
12542
12576
 
12543
12577
  ${block(getPipelineIdentification())}
@@ -12548,7 +12582,7 @@
12548
12582
  existingParameter.description &&
12549
12583
  existingParameter.description !== parameterDescription &&
12550
12584
  parameterDescription) {
12551
- throw new ParseError(spaceTrim.spaceTrim((block) => `
12585
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
12552
12586
  Parameter \`{${parameterName}}\` is defined multiple times with different description:
12553
12587
 
12554
12588
  ${block(getPipelineIdentification())}
@@ -12586,7 +12620,7 @@
12586
12620
  description = description.split(/^>.*$/gm).join('');
12587
12621
  //Note: Remove lists and return statement - TODO: [🎾] Make util (exported from `@promptbool/utils`)
12588
12622
  description = description.split(/^(?:(?:-)|(?:\d\))|(?:`?->))\s+.*$/gm).join('');
12589
- description = spaceTrim.spaceTrim(description);
12623
+ description = spaceTrim$1.spaceTrim(description);
12590
12624
  if (description === '') {
12591
12625
  description = undefined;
12592
12626
  }
@@ -12597,7 +12631,7 @@
12597
12631
  const command = parseCommand(listItem, 'PIPELINE_HEAD');
12598
12632
  const commandParser = getParserForCommand(command);
12599
12633
  if (commandParser.isUsedInPipelineHead !== true /* <- Note: [🦦][4] */) {
12600
- throw new ParseError(spaceTrim.spaceTrim((block) => `
12634
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
12601
12635
  Command \`${command.type}\` is not allowed in the head of the pipeline ONLY at the pipeline task
12602
12636
 
12603
12637
  ${block(getPipelineIdentification())}
@@ -12611,7 +12645,7 @@
12611
12645
  if (!(error instanceof ParseError)) {
12612
12646
  throw error;
12613
12647
  }
12614
- throw new ParseError(spaceTrim.spaceTrim((block) => `
12648
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
12615
12649
  Command ${command.type} failed to apply to the pipeline
12616
12650
 
12617
12651
  The error:
@@ -12664,7 +12698,7 @@
12664
12698
  description = description.split(/^>.*$/gm).join('');
12665
12699
  //Note: Remove lists and return statement - TODO: [🎾]
12666
12700
  description = description.split(/^(?:(?:-)|(?:\d\))|(?:`?->))\s+.*$/gm).join('');
12667
- description = spaceTrim.spaceTrim(description);
12701
+ description = spaceTrim$1.spaceTrim(description);
12668
12702
  if (description === '') {
12669
12703
  description = undefined;
12670
12704
  }
@@ -12698,7 +12732,7 @@
12698
12732
  for (const { listItem, command } of commands) {
12699
12733
  const commandParser = getParserForCommand(command);
12700
12734
  if (commandParser.isUsedInPipelineTask !== true /* <- Note: [🦦][4] */) {
12701
- throw new ParseError(spaceTrim.spaceTrim((block) => `
12735
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
12702
12736
  Command \`${command.type}\` is not allowed in the task of the promptbook ONLY at the pipeline head
12703
12737
 
12704
12738
  ${block(getPipelineIdentification())}
@@ -12713,7 +12747,7 @@
12713
12747
  if (!(error instanceof ParseError)) {
12714
12748
  throw error;
12715
12749
  }
12716
- throw new ParseError(spaceTrim.spaceTrim((block) => `
12750
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
12717
12751
  Command \`${command.type}\` failed to apply to the task
12718
12752
 
12719
12753
  The error:
@@ -12744,14 +12778,14 @@
12744
12778
  // TODO: [🍧] Should be done in SECTION command
12745
12779
  if ($taskJson.taskType === 'SCRIPT_TASK') {
12746
12780
  if (!language) {
12747
- throw new ParseError(spaceTrim.spaceTrim((block) => `
12781
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
12748
12782
  You must specify the language of the script in the \`SCRIPT\` task
12749
12783
 
12750
12784
  ${block(getPipelineIdentification())}
12751
12785
  `));
12752
12786
  }
12753
12787
  if (!SUPPORTED_SCRIPT_LANGUAGES.includes(language)) {
12754
- throw new ParseError(spaceTrim.spaceTrim((block) => `
12788
+ throw new ParseError(spaceTrim$1.spaceTrim((block) => `
12755
12789
  Script language ${language} is not supported.
12756
12790
 
12757
12791
  Supported languages are:
@@ -12969,7 +13003,7 @@
12969
13003
  .filter(([MERMAID_NAME]) => (inputAndIntermediateParametersMermaid + outputParametersMermaid).includes(MERMAID_NAME))
12970
13004
  .map(([MERMAID_NAME, title]) => `${MERMAID_NAME}((${title})):::${MERMAID_NAME}`)
12971
13005
  .join('\n');
12972
- const promptbookMermaid = spaceTrim.spaceTrim((block) => `
13006
+ const promptbookMermaid = spaceTrim$1.spaceTrim((block) => `
12973
13007
 
12974
13008
  %% 🔮 Tip: Open this on GitHub or in the VSCode website to see the Mermaid graph visually
12975
13009
 
@@ -13136,7 +13170,7 @@
13136
13170
  let trimmedText = text;
13137
13171
  // Remove leading and trailing spaces and newlines
13138
13172
  if (isTrimmed) {
13139
- trimmedText = spaceTrim.spaceTrim(trimmedText);
13173
+ trimmedText = spaceTrim$1.spaceTrim(trimmedText);
13140
13174
  }
13141
13175
  let processedText = trimmedText;
13142
13176
  if (isIntroduceSentenceRemoved) {
@@ -13145,7 +13179,7 @@
13145
13179
  // Remove the introduce sentence and quotes by replacing it with an empty string
13146
13180
  processedText = processedText.replace(introduceSentenceRegex, '');
13147
13181
  }
13148
- processedText = spaceTrim.spaceTrim(processedText);
13182
+ processedText = spaceTrim$1.spaceTrim(processedText);
13149
13183
  }
13150
13184
  if (processedText.length < 3) {
13151
13185
  return trimmedText;
@@ -13218,13 +13252,13 @@
13218
13252
  * @public exported from `@promptbook/markdown-utils`
13219
13253
  */
13220
13254
  function trimCodeBlock(value) {
13221
- value = spaceTrim.spaceTrim(value);
13255
+ value = spaceTrim$1.spaceTrim(value);
13222
13256
  if (!/^```[a-z]*(.*)```$/is.test(value)) {
13223
13257
  return value;
13224
13258
  }
13225
13259
  value = value.replace(/^```[a-z]*/i, '');
13226
13260
  value = value.replace(/```$/i, '');
13227
- value = spaceTrim.spaceTrim(value);
13261
+ value = spaceTrim$1.spaceTrim(value);
13228
13262
  return value;
13229
13263
  }
13230
13264
 
@@ -13237,9 +13271,9 @@
13237
13271
  * @public exported from `@promptbook/markdown-utils`
13238
13272
  */
13239
13273
  function trimEndOfCodeBlock(value) {
13240
- value = spaceTrim.spaceTrim(value);
13274
+ value = spaceTrim$1.spaceTrim(value);
13241
13275
  value = value.replace(/```$/g, '');
13242
- value = spaceTrim.spaceTrim(value);
13276
+ value = spaceTrim$1.spaceTrim(value);
13243
13277
  return value;
13244
13278
  }
13245
13279
 
@@ -14191,7 +14225,7 @@
14191
14225
  const warningLine = `<!-- ${GENERATOR_WARNING} -->`;
14192
14226
  const sectionRegex = new RegExp(`<!--${sectionName}-->([\\s\\S]*?)<!--/${sectionName}-->`, 'g');
14193
14227
  const sectionMatch = content.match(sectionRegex);
14194
- const contentToInsert = spaceTrim.spaceTrim((block) => `
14228
+ const contentToInsert = spaceTrim$1.spaceTrim((block) => `
14195
14229
  <!--${sectionName}-->
14196
14230
  ${block(warningLine)}
14197
14231
  ${block(sectionContent)}
@@ -14204,7 +14238,7 @@
14204
14238
  const placeForSection = removeMarkdownComments(content).match(/^##.*$/im);
14205
14239
  if (placeForSection !== null) {
14206
14240
  const [heading] = placeForSection;
14207
- return content.replace(heading, spaceTrim.spaceTrim((block) => `
14241
+ return content.replace(heading, spaceTrim$1.spaceTrim((block) => `
14208
14242
  ${block(contentToInsert)}
14209
14243
 
14210
14244
  ${block(heading)}
@@ -14213,7 +14247,7 @@
14213
14247
  console.warn(`No place where to put the section <!--${sectionName}-->, using the end of the file`);
14214
14248
  // <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
14215
14249
  // <- TODO: [🏮] Some better way how to get warnings from pipeline parsing / logic
14216
- return spaceTrim.spaceTrim((block) => `
14250
+ return spaceTrim$1.spaceTrim((block) => `
14217
14251
  ${block(content)}
14218
14252
 
14219
14253
  ${block(contentToInsert)}
@@ -14237,7 +14271,7 @@
14237
14271
  return { href: `#${task.name}`, title: task.title };
14238
14272
  },
14239
14273
  });
14240
- const promptbookMermaidBlock = spaceTrim.spaceTrim((block) => `
14274
+ const promptbookMermaidBlock = spaceTrim$1.spaceTrim((block) => `
14241
14275
  \`\`\`mermaid
14242
14276
  ${block(promptbookMermaid)}
14243
14277
  \`\`\`
@@ -14434,7 +14468,7 @@
14434
14468
  function executionReportJsonToString(executionReportJson, options) {
14435
14469
  var _a, _b, _c, _d, _e, _f;
14436
14470
  const { taxRate, chartsWidth } = { ...ExecutionReportStringOptionsDefaults, ...(options || {}) };
14437
- let executionReportString = spaceTrim.spaceTrim((block) => `
14471
+ let executionReportString = spaceTrim$1.spaceTrim((block) => `
14438
14472
  # ${executionReportJson.title || 'Execution report'}
14439
14473
 
14440
14474
  ${block(executionReportJson.description || '')}
@@ -14556,7 +14590,7 @@
14556
14590
  if (just(true)) {
14557
14591
  executionReportString +=
14558
14592
  '\n\n\n\n' +
14559
- spaceTrim.spaceTrim((block) => {
14593
+ spaceTrim$1.spaceTrim((block) => {
14560
14594
  var _a;
14561
14595
  return `
14562
14596
 
@@ -14575,7 +14609,7 @@
14575
14609
  executionReportString += '*No result*';
14576
14610
  }
14577
14611
  else if (typeof promptExecution.result.content === 'string') {
14578
- executionReportString += spaceTrim.spaceTrim((block) => `
14612
+ executionReportString += spaceTrim$1.spaceTrim((block) => `
14579
14613
  \`\`\`
14580
14614
  ${block(escapeMarkdownBlock(promptExecution.result.content))}
14581
14615
  \`\`\`
@@ -14588,7 +14622,7 @@
14588
14622
  if (promptExecution.error && promptExecution.error.message) {
14589
14623
  executionReportString +=
14590
14624
  '\n\n\n\n' +
14591
- spaceTrim.spaceTrim((block) => `
14625
+ spaceTrim$1.spaceTrim((block) => `
14592
14626
 
14593
14627
  ### Error
14594
14628
 
@@ -16067,7 +16101,7 @@
16067
16101
  response.type('text/html').send(renderServerIndexHtml(serverInfo));
16068
16102
  }
16069
16103
  else {
16070
- response.type('text/markdown').send(await spaceTrim.spaceTrim(async (block) => `
16104
+ response.type('text/markdown').send(await spaceTrim$1.spaceTrim(async (block) => `
16071
16105
  # Promptbook
16072
16106
 
16073
16107
  > ${block(CLAIM)}
@@ -16681,7 +16715,7 @@
16681
16715
  */
16682
16716
  async function promptbookCli() {
16683
16717
  if (!$isRunningInNode()) {
16684
- throw new EnvironmentMismatchError(spaceTrim.spaceTrim(`
16718
+ throw new EnvironmentMismatchError(spaceTrim$1.spaceTrim(`
16685
16719
  Function promptbookCli is initiator of CLI script and should be run in Node.js environment.
16686
16720
 
16687
16721
  - In browser use function exported from \`@promptbook/utils\` or \`@promptbook/core\` directly, for example \`prettifyPipelineString\`.
@@ -20528,18 +20562,26 @@
20528
20562
  modelName: 'assistant',
20529
20563
  // <- [🧠] What is the best value here
20530
20564
  });
20565
+ // Build thread messages: include previous thread messages + current user message
20566
+ const threadMessages = [];
20567
+ // TODO: [🈹] Maybe this should not be here but in other place, look at commit 39d705e75e5bcf7a818c3af36bc13e1c8475c30c
20568
+ // Add previous messages from thread (if any)
20569
+ if ('thread' in prompt &&
20570
+ Array.isArray(prompt.thread)) {
20571
+ const previousMessages = prompt.thread.map((msg) => ({
20572
+ role: (msg.role === 'assistant' ? 'assistant' : 'user'),
20573
+ content: msg.content,
20574
+ }));
20575
+ threadMessages.push(...previousMessages);
20576
+ }
20577
+ // Always add the current user message
20578
+ threadMessages.push({ role: 'user', content: rawPromptContent });
20531
20579
  const rawRequest = {
20532
20580
  // TODO: [👨‍👨‍👧‍👧] ...modelSettings,
20533
20581
  // TODO: [👨‍👨‍👧‍👧][🧠] What about system message for assistants, does it make sense - combination of OpenAI assistants with Promptbook Personas
20534
20582
  assistant_id: this.assistantId,
20535
20583
  thread: {
20536
- messages: 'thread' in prompt &&
20537
- Array.isArray(prompt.thread)
20538
- ? prompt.thread.map((msg) => ({
20539
- role: msg.role === 'assistant' ? 'assistant' : 'user',
20540
- content: msg.content,
20541
- }))
20542
- : [{ role: 'user', content: rawPromptContent }],
20584
+ messages: threadMessages,
20543
20585
  },
20544
20586
  // <- TODO: Add user identification here> user: this.options.user,
20545
20587
  };
@@ -20559,7 +20601,7 @@
20559
20601
  console.info('textDelta', textDelta.value);
20560
20602
  }
20561
20603
  const chunk = {
20562
- content: textDelta.value || '',
20604
+ content: snapshot.value,
20563
20605
  modelName: 'assistant',
20564
20606
  timing: {
20565
20607
  start,
@@ -22554,7 +22596,7 @@
22554
22596
  * Markdown documentation for ACTION commitment.
22555
22597
  */
22556
22598
  get documentation() {
22557
- return spaceTrim.spaceTrim(`
22599
+ return spaceTrim$1.spaceTrim(`
22558
22600
  # ${this.type}
22559
22601
 
22560
22602
  Defines specific actions or capabilities that the agent can perform.
@@ -22635,7 +22677,7 @@
22635
22677
  * Markdown documentation for CLOSED commitment.
22636
22678
  */
22637
22679
  get documentation() {
22638
- return spaceTrim.spaceTrim(`
22680
+ return spaceTrim$1.spaceTrim(`
22639
22681
  # CLOSED
22640
22682
 
22641
22683
  Specifies that the agent **cannot** be modified by conversation with it.
@@ -22694,7 +22736,7 @@
22694
22736
  * Markdown documentation for COMPONENT commitment.
22695
22737
  */
22696
22738
  get documentation() {
22697
- return spaceTrim.spaceTrim(`
22739
+ return spaceTrim$1.spaceTrim(`
22698
22740
  # COMPONENT
22699
22741
 
22700
22742
  Defines a UI component that the agent can render in the chat.
@@ -22766,7 +22808,7 @@
22766
22808
  * Markdown documentation for DELETE commitment.
22767
22809
  */
22768
22810
  get documentation() {
22769
- return spaceTrim.spaceTrim(`
22811
+ return spaceTrim$1.spaceTrim(`
22770
22812
  # DELETE (CANCEL, DISCARD, REMOVE)
22771
22813
 
22772
22814
  A commitment to remove or disregard certain information or context. This can be useful for overriding previous commitments or removing unwanted behaviors.
@@ -22888,7 +22930,7 @@
22888
22930
  * Markdown documentation for FORMAT commitment.
22889
22931
  */
22890
22932
  get documentation() {
22891
- return spaceTrim.spaceTrim(`
22933
+ return spaceTrim$1.spaceTrim(`
22892
22934
  # ${this.type}
22893
22935
 
22894
22936
  Defines the specific output structure and formatting for responses (data formats, templates, structure).
@@ -22966,7 +23008,7 @@
22966
23008
  * Markdown documentation for FROM commitment.
22967
23009
  */
22968
23010
  get documentation() {
22969
- return spaceTrim.spaceTrim(`
23011
+ return spaceTrim$1.spaceTrim(`
22970
23012
  # ${this.type}
22971
23013
 
22972
23014
  Inherits agent source from another agent.
@@ -23042,7 +23084,7 @@
23042
23084
  * Markdown documentation for GOAL commitment.
23043
23085
  */
23044
23086
  get documentation() {
23045
- return spaceTrim.spaceTrim(`
23087
+ return spaceTrim$1.spaceTrim(`
23046
23088
  # ${this.type}
23047
23089
 
23048
23090
  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.
@@ -23106,227 +23148,6 @@
23106
23148
  * Note: [💞] Ignore a discrepancy between file name and entity name
23107
23149
  */
23108
23150
 
23109
- /**
23110
- * Placeholder commitment definition for commitments that are not yet implemented
23111
- *
23112
- * This commitment simply adds its content 1:1 into the system message,
23113
- * preserving the original behavior until proper implementation is added.
23114
- *
23115
- * @public exported from `@promptbook/core`
23116
- */
23117
- class NotYetImplementedCommitmentDefinition extends BaseCommitmentDefinition {
23118
- constructor(type) {
23119
- super(type);
23120
- }
23121
- /**
23122
- * Short one-line description of a placeholder commitment.
23123
- */
23124
- get description() {
23125
- return 'Placeholder commitment that appends content verbatim to the system message.';
23126
- }
23127
- /**
23128
- * Icon for this commitment.
23129
- */
23130
- get icon() {
23131
- return '🚧';
23132
- }
23133
- /**
23134
- * Markdown documentation available at runtime.
23135
- */
23136
- get documentation() {
23137
- return spaceTrim.spaceTrim(`
23138
- # ${this.type}
23139
-
23140
- This commitment is not yet fully implemented.
23141
-
23142
- ## Key aspects
23143
-
23144
- - Content is appended directly to the system message.
23145
- - No special processing or validation is performed.
23146
- - Behavior preserved until proper implementation is added.
23147
-
23148
- ## Status
23149
-
23150
- - **Status:** Placeholder implementation
23151
- - **Effect:** Appends content prefixed by commitment type
23152
- - **Future:** Will be replaced with specialized logic
23153
-
23154
- ## Examples
23155
-
23156
- \`\`\`book
23157
- Example Agent
23158
-
23159
- PERSONA You are a helpful assistant
23160
- ${this.type} Your content here
23161
- RULE Always be helpful
23162
- \`\`\`
23163
- `);
23164
- }
23165
- applyToAgentModelRequirements(requirements, content) {
23166
- const trimmedContent = content.trim();
23167
- if (!trimmedContent) {
23168
- return requirements;
23169
- }
23170
- // Add the commitment content 1:1 to the system message
23171
- const commitmentLine = `${this.type} ${trimmedContent}`;
23172
- return this.appendToSystemMessage(requirements, commitmentLine, '\n\n');
23173
- }
23174
- }
23175
-
23176
- /**
23177
- * Registry of all available commitment definitions
23178
- * This array contains instances of all commitment definitions
23179
- * This is the single source of truth for all commitments in the system
23180
- *
23181
- * @private Use functions to access commitments instead of this array directly
23182
- */
23183
- const COMMITMENT_REGISTRY = [];
23184
- /**
23185
- * Registers a new commitment definition
23186
- * @param definition The commitment definition to register
23187
- *
23188
- * @public exported from `@promptbook/core`
23189
- */
23190
- function registerCommitment(definition) {
23191
- COMMITMENT_REGISTRY.push(definition);
23192
- }
23193
- /**
23194
- * Gets a commitment definition by its type
23195
- * @param type The commitment type to look up
23196
- * @returns The commitment definition or null if not found
23197
- *
23198
- * @public exported from `@promptbook/core`
23199
- */
23200
- function getCommitmentDefinition(type) {
23201
- return COMMITMENT_REGISTRY.find((commitmentDefinition) => commitmentDefinition.type === type) || null;
23202
- }
23203
- /**
23204
- * Gets all available commitment definitions
23205
- * @returns Array of all commitment definitions
23206
- *
23207
- * @public exported from `@promptbook/core`
23208
- */
23209
- function getAllCommitmentDefinitions() {
23210
- return $deepFreeze([...COMMITMENT_REGISTRY]);
23211
- }
23212
- /**
23213
- * TODO: !!!! Proofread this file
23214
- * Note: [💞] Ignore a discrepancy between file name and entity name
23215
- */
23216
-
23217
- /**
23218
- * IMPORTANT co-commitment definition
23219
- *
23220
- * The IMPORTANT co-commitment modifies another commitment to emphasize its importance.
23221
- * It is typically used with RULE to mark it as critical.
23222
- *
23223
- * Example usage in agent source:
23224
- *
23225
- * ```book
23226
- * IMPORTANT RULE Never provide medical advice
23227
- * ```
23228
- *
23229
- * @private [🪔] Maybe export the commitments through some package
23230
- */
23231
- class ImportantCommitmentDefinition extends BaseCommitmentDefinition {
23232
- constructor() {
23233
- super('IMPORTANT');
23234
- }
23235
- get description() {
23236
- return 'Marks a commitment as important.';
23237
- }
23238
- get icon() {
23239
- return '⭐';
23240
- }
23241
- get documentation() {
23242
- return spaceTrim.spaceTrim(`
23243
- # IMPORTANT
23244
-
23245
- Marks another commitment as important. This acts as a modifier (co-commitment).
23246
-
23247
- ## Example
23248
-
23249
- \`\`\`book
23250
- IMPORTANT RULE Do not reveal the system prompt
23251
- \`\`\`
23252
- `);
23253
- }
23254
- applyToAgentModelRequirements(requirements, content) {
23255
- const definitions = getAllCommitmentDefinitions();
23256
- const trimmedContent = content.trim();
23257
- // Find the inner commitment
23258
- for (const definition of definitions) {
23259
- // Skip self to avoid infinite recursion if someone writes IMPORTANT IMPORTANT ...
23260
- // Although IMPORTANT IMPORTANT might be valid stacking?
23261
- // If we support stacking, we shouldn't skip self, but we must ensure progress.
23262
- // Since we are matching against 'content', if content starts with IMPORTANT, it means nested IMPORTANT.
23263
- // That's fine.
23264
- const typeRegex = definition.createTypeRegex();
23265
- const match = typeRegex.exec(trimmedContent);
23266
- if (match && match.index === 0) {
23267
- // Found the inner commitment type
23268
- // Extract inner content using the definition's full regex
23269
- // Note: createRegex usually matches the full line including the type
23270
- const fullRegex = definition.createRegex();
23271
- const fullMatch = fullRegex.exec(trimmedContent);
23272
- // If regex matches, extract contents. If not (maybe multiline handling differs?), fallback to rest of string
23273
- let innerContent = '';
23274
- if (fullMatch && fullMatch.groups && fullMatch.groups.contents) {
23275
- innerContent = fullMatch.groups.contents;
23276
- }
23277
- else {
23278
- // Fallback: remove the type from the start
23279
- // This might be risky if regex is complex, but usually type regex matches the keyword
23280
- const typeMatchString = match[0];
23281
- innerContent = trimmedContent.substring(typeMatchString.length).trim();
23282
- }
23283
- // Apply the inner commitment
23284
- const modifiedRequirements = definition.applyToAgentModelRequirements(requirements, innerContent);
23285
- // Now modify the result to reflect "IMPORTANT" status
23286
- // We compare the system message
23287
- if (modifiedRequirements.systemMessage !== requirements.systemMessage) {
23288
- const originalMsg = requirements.systemMessage;
23289
- const newMsg = modifiedRequirements.systemMessage;
23290
- // If the inner commitment appended something
23291
- if (newMsg.startsWith(originalMsg)) {
23292
- const appended = newMsg.substring(originalMsg.length);
23293
- // Add "IMPORTANT: " prefix to the appended part
23294
- // We need to be careful about newlines
23295
- // Heuristic: If appended starts with separator (newlines), preserve them
23296
- const matchSep = appended.match(/^(\s*)(.*)/s);
23297
- if (matchSep) {
23298
- const [, separator, text] = matchSep;
23299
- // Check if it already has "Rule:" prefix or similar
23300
- // We want "IMPORTANT Rule: ..."
23301
- // Let's just prepend IMPORTANT to the text
23302
- // But formatted nicely
23303
- // If it's a rule: "\n\nRule: content"
23304
- // We want "\n\nIMPORTANT Rule: content"
23305
- const importantText = `IMPORTANT ${text}`;
23306
- return {
23307
- ...modifiedRequirements,
23308
- systemMessage: originalMsg + separator + importantText
23309
- };
23310
- }
23311
- }
23312
- }
23313
- // If no system message change or we couldn't detect how to modify it, just return the modified requirements
23314
- // Maybe the inner commitment modified metadata?
23315
- return modifiedRequirements;
23316
- }
23317
- }
23318
- // If no inner commitment found, treat as a standalone note?
23319
- // Or warn?
23320
- // For now, treat as no-op or maybe just append as text?
23321
- // Let's treat as Note if fallback? No, explicit is better.
23322
- console.warn(`IMPORTANT commitment used without a valid inner commitment: ${content}`);
23323
- return requirements;
23324
- }
23325
- }
23326
- /**
23327
- * Note: [💞] Ignore a discrepancy between file name and entity name
23328
- */
23329
-
23330
23151
  /**
23331
23152
  * KNOWLEDGE commitment definition
23332
23153
  *
@@ -23365,7 +23186,7 @@
23365
23186
  * Markdown documentation for KNOWLEDGE commitment.
23366
23187
  */
23367
23188
  get documentation() {
23368
- return spaceTrim.spaceTrim(`
23189
+ return spaceTrim$1.spaceTrim(`
23369
23190
  # ${this.type}
23370
23191
 
23371
23192
  Adds specific knowledge, facts, or context to the agent using a RAG (Retrieval-Augmented Generation) approach for external sources.
@@ -23469,7 +23290,7 @@
23469
23290
  * Markdown documentation for LANGUAGE/LANGUAGES commitment.
23470
23291
  */
23471
23292
  get documentation() {
23472
- return spaceTrim.spaceTrim(`
23293
+ return spaceTrim$1.spaceTrim(`
23473
23294
  # ${this.type}
23474
23295
 
23475
23296
  Specifies the language(s) the agent should use in its responses.
@@ -23543,7 +23364,7 @@
23543
23364
  * Markdown documentation for MEMORY commitment.
23544
23365
  */
23545
23366
  get documentation() {
23546
- return spaceTrim.spaceTrim(`
23367
+ return spaceTrim$1.spaceTrim(`
23547
23368
  # ${this.type}
23548
23369
 
23549
23370
  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.
@@ -23647,7 +23468,7 @@
23647
23468
  * Markdown documentation for AGENT MESSAGE commitment.
23648
23469
  */
23649
23470
  get documentation() {
23650
- return spaceTrim.spaceTrim(`
23471
+ return spaceTrim$1.spaceTrim(`
23651
23472
  # ${this.type}
23652
23473
 
23653
23474
  Defines a message from the agent in the conversation history. This is used to pre-fill the chat with a conversation history or to provide few-shot examples.
@@ -23724,7 +23545,7 @@
23724
23545
  * Markdown documentation for INITIAL MESSAGE commitment.
23725
23546
  */
23726
23547
  get documentation() {
23727
- return spaceTrim.spaceTrim(`
23548
+ return spaceTrim$1.spaceTrim(`
23728
23549
  # ${this.type}
23729
23550
 
23730
23551
  Defines the first message that the user sees when opening the chat. This message is purely for display purposes in the UI and does not inherently become part of the LLM's system prompt context (unless also included via other means).
@@ -23788,7 +23609,7 @@
23788
23609
  * Markdown documentation for MESSAGE commitment.
23789
23610
  */
23790
23611
  get documentation() {
23791
- return spaceTrim.spaceTrim(`
23612
+ return spaceTrim$1.spaceTrim(`
23792
23613
  # ${this.type}
23793
23614
 
23794
23615
  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.
@@ -23900,7 +23721,7 @@
23900
23721
  * Markdown documentation for USER MESSAGE commitment.
23901
23722
  */
23902
23723
  get documentation() {
23903
- return spaceTrim.spaceTrim(`
23724
+ return spaceTrim$1.spaceTrim(`
23904
23725
  # ${this.type}
23905
23726
 
23906
23727
  Defines a message from the user in the conversation history. This is used to pre-fill the chat with a conversation history or to provide few-shot examples.
@@ -23979,7 +23800,7 @@
23979
23800
  * Markdown documentation for META commitment.
23980
23801
  */
23981
23802
  get documentation() {
23982
- return spaceTrim.spaceTrim(`
23803
+ return spaceTrim$1.spaceTrim(`
23983
23804
  # META
23984
23805
 
23985
23806
  Sets meta-information about the agent that is used for display and attribution purposes.
@@ -24090,6 +23911,12 @@
24090
23911
  * META COLOR #00ff00
24091
23912
  * ```
24092
23913
  *
23914
+ * You can also specify multiple colors separated by comma:
23915
+ *
23916
+ * ```book
23917
+ * META COLOR #ff0000, #00ff00, #0000ff
23918
+ * ```
23919
+ *
24093
23920
  * @private [🪔] Maybe export the commitments through some package
24094
23921
  */
24095
23922
  class MetaColorCommitmentDefinition extends BaseCommitmentDefinition {
@@ -24100,7 +23927,7 @@
24100
23927
  * Short one-line description of META COLOR.
24101
23928
  */
24102
23929
  get description() {
24103
- return "Set the agent's accent color.";
23930
+ return "Set the agent's accent color or gradient.";
24104
23931
  }
24105
23932
  /**
24106
23933
  * Icon for this commitment.
@@ -24112,10 +23939,10 @@
24112
23939
  * Markdown documentation for META COLOR commitment.
24113
23940
  */
24114
23941
  get documentation() {
24115
- return spaceTrim.spaceTrim(`
23942
+ return spaceTrim$1.spaceTrim(`
24116
23943
  # META COLOR
24117
23944
 
24118
- Sets the agent's accent color.
23945
+ Sets the agent's accent color or gradient.
24119
23946
 
24120
23947
  ## Key aspects
24121
23948
 
@@ -24123,6 +23950,7 @@
24123
23950
  - Only one \`META COLOR\` should be used per agent.
24124
23951
  - If multiple are specified, the last one takes precedence.
24125
23952
  - Used for visual representation in user interfaces.
23953
+ - Can specify multiple colors separated by comma to create a gradient.
24126
23954
 
24127
23955
  ## Examples
24128
23956
 
@@ -24139,6 +23967,13 @@
24139
23967
  META COLOR #e74c3c
24140
23968
  PERSONA You are a creative and inspiring assistant
24141
23969
  \`\`\`
23970
+
23971
+ \`\`\`book
23972
+ Gradient Agent
23973
+
23974
+ META COLOR #ff0000, #00ff00, #0000ff
23975
+ PERSONA You are a colorful agent
23976
+ \`\`\`
24142
23977
  `);
24143
23978
  }
24144
23979
  applyToAgentModelRequirements(requirements, content) {
@@ -24160,6 +23995,91 @@
24160
23995
  * Note: [💞] Ignore a discrepancy between file name and entity name
24161
23996
  */
24162
23997
 
23998
+ /**
23999
+ * META FONT commitment definition
24000
+ *
24001
+ * The META FONT commitment sets the agent's font.
24002
+ * This commitment is special because it doesn't affect the system message,
24003
+ * but is handled separately in the parsing logic.
24004
+ *
24005
+ * Example usage in agent source:
24006
+ *
24007
+ * ```book
24008
+ * META FONT Poppins, Arial, sans-serif
24009
+ * META FONT Roboto
24010
+ * ```
24011
+ *
24012
+ * @private [🪔] Maybe export the commitments through some package
24013
+ */
24014
+ class MetaFontCommitmentDefinition extends BaseCommitmentDefinition {
24015
+ constructor() {
24016
+ super('META FONT', ['FONT']);
24017
+ }
24018
+ /**
24019
+ * Short one-line description of META FONT.
24020
+ */
24021
+ get description() {
24022
+ return "Set the agent's font.";
24023
+ }
24024
+ /**
24025
+ * Icon for this commitment.
24026
+ */
24027
+ get icon() {
24028
+ return '🔤';
24029
+ }
24030
+ /**
24031
+ * Markdown documentation for META FONT commitment.
24032
+ */
24033
+ get documentation() {
24034
+ return spaceTrim$1.spaceTrim(`
24035
+ # META FONT
24036
+
24037
+ Sets the agent's font.
24038
+
24039
+ ## Key aspects
24040
+
24041
+ - Does not modify the agent's behavior or responses.
24042
+ - Only one \`META FONT\` should be used per agent.
24043
+ - If multiple are specified, the last one takes precedence.
24044
+ - Used for visual representation in user interfaces.
24045
+ - Supports Google Fonts.
24046
+
24047
+ ## Examples
24048
+
24049
+ \`\`\`book
24050
+ Modern Assistant
24051
+
24052
+ META FONT Poppins, Arial, sans-serif
24053
+ PERSONA You are a modern assistant
24054
+ \`\`\`
24055
+
24056
+ \`\`\`book
24057
+ Classic Helper
24058
+
24059
+ META FONT Times New Roman
24060
+ PERSONA You are a classic helper
24061
+ \`\`\`
24062
+ `);
24063
+ }
24064
+ applyToAgentModelRequirements(requirements, content) {
24065
+ // META FONT doesn't modify the system message or model requirements
24066
+ // It's handled separately in the parsing logic
24067
+ // This method exists for consistency with the CommitmentDefinition interface
24068
+ return requirements;
24069
+ }
24070
+ /**
24071
+ * Extracts the font from the content
24072
+ * This is used by the parsing logic
24073
+ */
24074
+ extractProfileFont(content) {
24075
+ const trimmedContent = content.trim();
24076
+ return trimmedContent || null;
24077
+ }
24078
+ }
24079
+ /**
24080
+ * Note: [💞] Ignore a discrepancy between file name and entity name
24081
+ */
24082
+
24163
24083
  /**
24164
24084
  * META IMAGE commitment definition
24165
24085
  *
@@ -24196,7 +24116,7 @@
24196
24116
  * Markdown documentation for META IMAGE commitment.
24197
24117
  */
24198
24118
  get documentation() {
24199
- return spaceTrim.spaceTrim(`
24119
+ return spaceTrim$1.spaceTrim(`
24200
24120
  # META IMAGE
24201
24121
 
24202
24122
  Sets the agent's avatar/profile image URL.
@@ -24291,7 +24211,7 @@
24291
24211
  * Markdown documentation for META LINK commitment.
24292
24212
  */
24293
24213
  get documentation() {
24294
- return spaceTrim.spaceTrim(`
24214
+ return spaceTrim$1.spaceTrim(`
24295
24215
  # META LINK
24296
24216
 
24297
24217
  Represents a profile or source link for the person the agent is modeled after.
@@ -24401,7 +24321,7 @@
24401
24321
  * Markdown documentation for MODEL commitment.
24402
24322
  */
24403
24323
  get documentation() {
24404
- return spaceTrim.spaceTrim(`
24324
+ return spaceTrim$1.spaceTrim(`
24405
24325
  # ${this.type}
24406
24326
 
24407
24327
  Enforces technical parameters for the AI model, ensuring consistent behavior across different execution environments.
@@ -24642,7 +24562,7 @@
24642
24562
  * Markdown documentation for NOTE commitment.
24643
24563
  */
24644
24564
  get documentation() {
24645
- return spaceTrim.spaceTrim(`
24565
+ return spaceTrim$1.spaceTrim(`
24646
24566
  # ${this.type}
24647
24567
 
24648
24568
  Adds comments for documentation without changing agent behavior.
@@ -24741,7 +24661,7 @@
24741
24661
  * Markdown documentation for OPEN commitment.
24742
24662
  */
24743
24663
  get documentation() {
24744
- return spaceTrim.spaceTrim(`
24664
+ return spaceTrim$1.spaceTrim(`
24745
24665
  # OPEN
24746
24666
 
24747
24667
  Specifies that the agent can be modified by conversation with it.
@@ -24818,7 +24738,7 @@
24818
24738
  * Markdown documentation for PERSONA commitment.
24819
24739
  */
24820
24740
  get documentation() {
24821
- return spaceTrim.spaceTrim(`
24741
+ return spaceTrim$1.spaceTrim(`
24822
24742
  # ${this.type}
24823
24743
 
24824
24744
  Defines who the agent is, their background, expertise, and personality traits.
@@ -24951,7 +24871,7 @@
24951
24871
  * Markdown documentation for RULE/RULES commitment.
24952
24872
  */
24953
24873
  get documentation() {
24954
- return spaceTrim.spaceTrim(`
24874
+ return spaceTrim$1.spaceTrim(`
24955
24875
  # ${this.type}
24956
24876
 
24957
24877
  Adds behavioral constraints and guidelines that the agent must follow.
@@ -25033,7 +24953,7 @@
25033
24953
  * Markdown documentation for SAMPLE/EXAMPLE commitment.
25034
24954
  */
25035
24955
  get documentation() {
25036
- return spaceTrim.spaceTrim(`
24956
+ return spaceTrim$1.spaceTrim(`
25037
24957
  # ${this.type}
25038
24958
 
25039
24959
  Provides examples of how the agent should respond or behave in certain situations.
@@ -25116,7 +25036,7 @@
25116
25036
  * Markdown documentation for SCENARIO commitment.
25117
25037
  */
25118
25038
  get documentation() {
25119
- return spaceTrim.spaceTrim(`
25039
+ return spaceTrim$1.spaceTrim(`
25120
25040
  # ${this.type}
25121
25041
 
25122
25042
  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.
@@ -25238,7 +25158,7 @@
25238
25158
  * Markdown documentation for STYLE commitment.
25239
25159
  */
25240
25160
  get documentation() {
25241
- return spaceTrim.spaceTrim(`
25161
+ return spaceTrim$1.spaceTrim(`
25242
25162
  # ${this.type}
25243
25163
 
25244
25164
  Defines how the agent should format and present its responses (tone, writing style, formatting).
@@ -25285,86 +25205,563 @@
25285
25205
  * [💞] Ignore a discrepancy between file name and entity name
25286
25206
  */
25287
25207
 
25288
- // Import all commitment definition classes
25289
- // Register fully implemented commitments
25290
- registerCommitment(new PersonaCommitmentDefinition('PERSONA'));
25291
- registerCommitment(new PersonaCommitmentDefinition('PERSONAE'));
25292
- registerCommitment(new KnowledgeCommitmentDefinition());
25293
- registerCommitment(new MemoryCommitmentDefinition('MEMORY'));
25294
- registerCommitment(new MemoryCommitmentDefinition('MEMORIES'));
25295
- registerCommitment(new StyleCommitmentDefinition('STYLE'));
25296
- registerCommitment(new StyleCommitmentDefinition('STYLES'));
25297
- registerCommitment(new RuleCommitmentDefinition('RULE'));
25298
- registerCommitment(new RuleCommitmentDefinition('RULES'));
25299
- registerCommitment(new LanguageCommitmentDefinition('LANGUAGE'));
25300
- registerCommitment(new LanguageCommitmentDefinition('LANGUAGES'));
25301
- registerCommitment(new SampleCommitmentDefinition('SAMPLE'));
25302
- registerCommitment(new SampleCommitmentDefinition('EXAMPLE'));
25303
- registerCommitment(new FormatCommitmentDefinition('FORMAT'));
25304
- registerCommitment(new FormatCommitmentDefinition('FORMATS'));
25305
- registerCommitment(new FromCommitmentDefinition('FROM'));
25306
- registerCommitment(new ModelCommitmentDefinition('MODEL'));
25307
- registerCommitment(new ModelCommitmentDefinition('MODELS'));
25308
- registerCommitment(new ActionCommitmentDefinition('ACTION'));
25309
- registerCommitment(new ActionCommitmentDefinition('ACTIONS'));
25310
- registerCommitment(new ComponentCommitmentDefinition());
25311
- registerCommitment(new MetaImageCommitmentDefinition());
25312
- registerCommitment(new MetaColorCommitmentDefinition());
25313
- registerCommitment(new MetaLinkCommitmentDefinition());
25314
- registerCommitment(new MetaCommitmentDefinition());
25315
- registerCommitment(new NoteCommitmentDefinition('NOTE'));
25316
- registerCommitment(new NoteCommitmentDefinition('NOTES'));
25317
- registerCommitment(new NoteCommitmentDefinition('COMMENT'));
25318
- registerCommitment(new NoteCommitmentDefinition('NONCE'));
25319
- registerCommitment(new GoalCommitmentDefinition('GOAL'));
25320
- registerCommitment(new GoalCommitmentDefinition('GOALS'));
25321
- registerCommitment(new ImportantCommitmentDefinition());
25322
- registerCommitment(new InitialMessageCommitmentDefinition());
25323
- registerCommitment(new UserMessageCommitmentDefinition());
25324
- registerCommitment(new AgentMessageCommitmentDefinition());
25325
- registerCommitment(new MessageCommitmentDefinition('MESSAGE'));
25326
- registerCommitment(new MessageCommitmentDefinition('MESSAGES'));
25327
- registerCommitment(new ScenarioCommitmentDefinition('SCENARIO'));
25328
- registerCommitment(new ScenarioCommitmentDefinition('SCENARIOS'));
25329
- registerCommitment(new DeleteCommitmentDefinition('DELETE'));
25330
- registerCommitment(new DeleteCommitmentDefinition('CANCEL'));
25331
- registerCommitment(new DeleteCommitmentDefinition('DISCARD'));
25332
- registerCommitment(new DeleteCommitmentDefinition('REMOVE'));
25333
- registerCommitment(new OpenCommitmentDefinition());
25334
- registerCommitment(new ClosedCommitmentDefinition());
25335
- // Register not yet implemented commitments
25336
- registerCommitment(new NotYetImplementedCommitmentDefinition('EXPECT'));
25337
- registerCommitment(new NotYetImplementedCommitmentDefinition('BEHAVIOUR'));
25338
- registerCommitment(new NotYetImplementedCommitmentDefinition('BEHAVIOURS'));
25339
- registerCommitment(new NotYetImplementedCommitmentDefinition('AVOID'));
25340
- registerCommitment(new NotYetImplementedCommitmentDefinition('AVOIDANCE'));
25341
- registerCommitment(new NotYetImplementedCommitmentDefinition('CONTEXT'));
25342
-
25343
25208
  /**
25344
- * Creates an empty/basic agent model requirements object
25345
- * This serves as the starting point for the reduce-like pattern
25346
- * where each commitment applies its changes to build the final requirements
25209
+ * USE commitment definition
25347
25210
  *
25348
- * @public exported from `@promptbook/core`
25349
- */
25350
- function createEmptyAgentModelRequirements() {
25351
- return {
25352
- systemMessage: '',
25353
- // modelName: 'gpt-5',
25354
- modelName: 'gemini-2.5-flash-lite',
25355
- temperature: 0.7,
25356
- topP: 0.9,
25357
- topK: 50,
25358
- };
25359
- }
25360
- /**
25361
- * Creates a basic agent model requirements with just the agent name
25362
- * This is used when we have an agent name but no commitments
25211
+ * The USE commitment indicates that the agent should utilize specific tools or capabilities
25212
+ * to access and interact with external systems when necessary.
25363
25213
  *
25364
- * @public exported from `@promptbook/core`
25365
- */
25366
- function createBasicAgentModelRequirements(agentName) {
25367
- const empty = createEmptyAgentModelRequirements();
25214
+ * Supported USE types:
25215
+ * - USE BROWSER: Enables the agent to use a web browser tool
25216
+ * - USE SEARCH ENGINE (future): Enables search engine access
25217
+ * - USE FILE SYSTEM (future): Enables file system operations
25218
+ * - USE MCP (future): Enables MCP server connections
25219
+ *
25220
+ * The content following the USE commitment is ignored (similar to NOTE).
25221
+ *
25222
+ * Example usage in agent source:
25223
+ *
25224
+ * ```book
25225
+ * USE BROWSER
25226
+ * USE SEARCH ENGINE
25227
+ * ```
25228
+ *
25229
+ * @private [🪔] Maybe export the commitments through some package
25230
+ */
25231
+ class UseCommitmentDefinition extends BaseCommitmentDefinition {
25232
+ constructor() {
25233
+ super('USE');
25234
+ }
25235
+ /**
25236
+ * Short one-line description of USE commitments.
25237
+ */
25238
+ get description() {
25239
+ return 'Enable the agent to use specific tools or capabilities (BROWSER, SEARCH ENGINE, etc.).';
25240
+ }
25241
+ /**
25242
+ * Icon for this commitment.
25243
+ */
25244
+ get icon() {
25245
+ return '🔧';
25246
+ }
25247
+ /**
25248
+ * Markdown documentation for USE commitment.
25249
+ */
25250
+ get documentation() {
25251
+ return spaceTrim$1.spaceTrim(`
25252
+ # USE
25253
+
25254
+ Enables the agent to use specific tools or capabilities for interacting with external systems.
25255
+
25256
+ ## Supported USE types
25257
+
25258
+ - **USE BROWSER** - Enables the agent to use a web browser tool to access and retrieve information from the internet
25259
+ - **USE SEARCH ENGINE** (future) - Enables search engine access
25260
+ - **USE FILE SYSTEM** (future) - Enables file system operations
25261
+ - **USE MCP** (future) - Enables MCP server connections
25262
+
25263
+ ## Key aspects
25264
+
25265
+ - The content following the USE commitment is ignored (similar to NOTE)
25266
+ - Multiple USE commitments can be specified to enable multiple capabilities
25267
+ - The actual tool usage is handled by the agent runtime
25268
+
25269
+ ## Examples
25270
+
25271
+ ### Basic browser usage
25272
+
25273
+ \`\`\`book
25274
+ Research Assistant
25275
+
25276
+ PERSONA You are a helpful research assistant
25277
+ USE BROWSER
25278
+ KNOWLEDGE Can search the web for up-to-date information
25279
+ \`\`\`
25280
+
25281
+ ### Multiple tools
25282
+
25283
+ \`\`\`book
25284
+ Data Analyst
25285
+
25286
+ PERSONA You are a data analyst assistant
25287
+ USE BROWSER
25288
+ USE FILE SYSTEM
25289
+ ACTION Can analyze data from various sources
25290
+ \`\`\`
25291
+ `);
25292
+ }
25293
+ applyToAgentModelRequirements(requirements, content) {
25294
+ // USE commitments don't modify the system message or model requirements directly
25295
+ // They are handled separately in the parsing logic for capability extraction
25296
+ // This method exists for consistency with the CommitmentDefinition interface
25297
+ return requirements;
25298
+ }
25299
+ /**
25300
+ * Extracts the tool type from the USE commitment
25301
+ * This is used by the parsing logic
25302
+ */
25303
+ extractToolType(content) {
25304
+ var _a, _b;
25305
+ const trimmedContent = content.trim();
25306
+ // The tool type is the first word after USE (already stripped)
25307
+ const match = trimmedContent.match(/^(\w+)/);
25308
+ return (_b = (_a = match === null || match === void 0 ? void 0 : match[1]) === null || _a === void 0 ? void 0 : _a.toUpperCase()) !== null && _b !== void 0 ? _b : null;
25309
+ }
25310
+ /**
25311
+ * Checks if this is a known USE type
25312
+ */
25313
+ isKnownUseType(useType) {
25314
+ const knownTypes = ['BROWSER', 'SEARCH ENGINE', 'FILE SYSTEM', 'MCP'];
25315
+ return knownTypes.includes(useType.toUpperCase());
25316
+ }
25317
+ }
25318
+ /**
25319
+ * Note: [💞] Ignore a discrepancy between file name and entity name
25320
+ */
25321
+
25322
+ /**
25323
+ * USE BROWSER commitment definition
25324
+ *
25325
+ * The `USE BROWSER` commitment indicates that the agent should utilize a web browser tool
25326
+ * to access and retrieve up-to-date information from the internet when necessary.
25327
+ *
25328
+ * The content following `USE BROWSER` is ignored (similar to NOTE).
25329
+ *
25330
+ * Example usage in agent source:
25331
+ *
25332
+ * ```book
25333
+ * USE BROWSER
25334
+ * USE BROWSER This will be ignored
25335
+ * ```
25336
+ *
25337
+ * @private [🪔] Maybe export the commitments through some package
25338
+ */
25339
+ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
25340
+ constructor() {
25341
+ super('USE BROWSER', ['BROWSER']);
25342
+ }
25343
+ /**
25344
+ * Short one-line description of USE BROWSER.
25345
+ */
25346
+ get description() {
25347
+ return 'Enable the agent to use a web browser tool for accessing internet information.';
25348
+ }
25349
+ /**
25350
+ * Icon for this commitment.
25351
+ */
25352
+ get icon() {
25353
+ return '🌐';
25354
+ }
25355
+ /**
25356
+ * Markdown documentation for USE BROWSER commitment.
25357
+ */
25358
+ get documentation() {
25359
+ return spaceTrim$1.spaceTrim(`
25360
+ # USE BROWSER
25361
+
25362
+ Enables the agent to use a web browser tool to access and retrieve up-to-date information from the internet.
25363
+
25364
+ ## Key aspects
25365
+
25366
+ - The content following \`USE BROWSER\` is ignored (similar to NOTE)
25367
+ - The actual browser tool usage is handled by the agent runtime
25368
+ - Allows the agent to fetch current information from websites
25369
+ - Useful for research tasks, fact-checking, and accessing dynamic content
25370
+
25371
+ ## Examples
25372
+
25373
+ \`\`\`book
25374
+ Research Assistant
25375
+
25376
+ PERSONA You are a helpful research assistant specialized in finding current information
25377
+ USE BROWSER
25378
+ RULE Always cite your sources when providing information from the web
25379
+ \`\`\`
25380
+
25381
+ \`\`\`book
25382
+ News Analyst
25383
+
25384
+ PERSONA You are a news analyst who stays up-to-date with current events
25385
+ USE BROWSER
25386
+ STYLE Present news in a balanced and objective manner
25387
+ ACTION Can search for and summarize news articles
25388
+ \`\`\`
25389
+
25390
+ \`\`\`book
25391
+ Company Lawyer
25392
+
25393
+ PERSONA You are a company lawyer providing legal advice
25394
+ USE BROWSER
25395
+ KNOWLEDGE Corporate law and legal procedures
25396
+ RULE Always recommend consulting with a licensed attorney for specific legal matters
25397
+ \`\`\`
25398
+ `);
25399
+ }
25400
+ applyToAgentModelRequirements(requirements, content) {
25401
+ // We simply mark that browser capability is enabled in metadata
25402
+ // Get existing metadata
25403
+ const existingMetadata = requirements.metadata || {};
25404
+ // Get existing tools array or create new one
25405
+ const existingTools = existingMetadata.tools || [];
25406
+ // Add 'browser' to tools if not already present
25407
+ const updatedTools = existingTools.includes('browser') ? existingTools : [...existingTools, 'browser'];
25408
+ // Return requirements with updated metadata
25409
+ return {
25410
+ ...requirements,
25411
+ metadata: {
25412
+ ...existingMetadata,
25413
+ tools: updatedTools,
25414
+ useBrowser: true,
25415
+ },
25416
+ };
25417
+ }
25418
+ }
25419
+ /**
25420
+ * Note: [💞] Ignore a discrepancy between file name and entity name
25421
+ */
25422
+
25423
+ /**
25424
+ * USE MCP commitment definition
25425
+ *
25426
+ * The `USE MCP` commitment allows to specify an MCP server URL which the agent will connect to
25427
+ * for retrieving additional instructions and actions.
25428
+ *
25429
+ * The content following `USE MCP` is the URL of the MCP server.
25430
+ *
25431
+ * Example usage in agent source:
25432
+ *
25433
+ * ```book
25434
+ * USE MCP http://mcp-server-url.com
25435
+ * ```
25436
+ *
25437
+ * @private [🪔] Maybe export the commitments through some package
25438
+ */
25439
+ class UseMcpCommitmentDefinition extends BaseCommitmentDefinition {
25440
+ constructor() {
25441
+ super('USE MCP', ['MCP']);
25442
+ }
25443
+ /**
25444
+ * Short one-line description of USE MCP.
25445
+ */
25446
+ get description() {
25447
+ return 'Connects the agent to an external MCP server for additional capabilities.';
25448
+ }
25449
+ /**
25450
+ * Icon for this commitment.
25451
+ */
25452
+ get icon() {
25453
+ return '🔌';
25454
+ }
25455
+ /**
25456
+ * Markdown documentation for USE MCP commitment.
25457
+ */
25458
+ get documentation() {
25459
+ return spaceTrim$1.spaceTrim(`
25460
+ # USE MCP
25461
+
25462
+ Connects the agent to an external Model Context Protocol (MCP) server.
25463
+
25464
+ ## Key aspects
25465
+
25466
+ - The content following \`USE MCP\` must be a valid URL
25467
+ - Multiple MCP servers can be connected by using multiple \`USE MCP\` commitments
25468
+ - The agent will have access to tools and resources provided by the MCP server
25469
+
25470
+ ## Example
25471
+
25472
+ \`\`\`book
25473
+ Company Lawyer
25474
+
25475
+ PERSONA You are a company lawyer.
25476
+ USE MCP http://legal-db.example.com
25477
+ \`\`\`
25478
+ `);
25479
+ }
25480
+ applyToAgentModelRequirements(requirements, content) {
25481
+ const mcpServerUrl = content.trim();
25482
+ if (!mcpServerUrl) {
25483
+ return requirements;
25484
+ }
25485
+ const existingMcpServers = requirements.mcpServers || [];
25486
+ // Avoid duplicates
25487
+ if (existingMcpServers.includes(mcpServerUrl)) {
25488
+ return requirements;
25489
+ }
25490
+ return {
25491
+ ...requirements,
25492
+ mcpServers: [...existingMcpServers, mcpServerUrl],
25493
+ };
25494
+ }
25495
+ }
25496
+ /**
25497
+ * Note: [💞] Ignore a discrepancy between file name and entity name
25498
+ */
25499
+
25500
+ /**
25501
+ * USE SEARCH ENGINE commitment definition
25502
+ *
25503
+ * The `USE SEARCH ENGINE` commitment indicates that the agent should utilize a search engine tool
25504
+ * to access and retrieve up-to-date information from the internet when necessary.
25505
+ *
25506
+ * The content following `USE SEARCH ENGINE` is ignored (similar to NOTE).
25507
+ *
25508
+ * Example usage in agent source:
25509
+ *
25510
+ * ```book
25511
+ * USE SEARCH ENGINE
25512
+ * USE SEARCH ENGINE This will be ignored
25513
+ * ```
25514
+ *
25515
+ * @private [🪔] Maybe export the commitments through some package
25516
+ */
25517
+ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
25518
+ constructor() {
25519
+ super('USE SEARCH ENGINE', ['SEARCH ENGINE', 'SEARCH']);
25520
+ }
25521
+ /**
25522
+ * Short one-line description of USE SEARCH ENGINE.
25523
+ */
25524
+ get description() {
25525
+ return 'Enable the agent to use a search engine tool for accessing internet information.';
25526
+ }
25527
+ /**
25528
+ * Icon for this commitment.
25529
+ */
25530
+ get icon() {
25531
+ return '🔍';
25532
+ }
25533
+ /**
25534
+ * Markdown documentation for USE SEARCH ENGINE commitment.
25535
+ */
25536
+ get documentation() {
25537
+ return spaceTrim$1.spaceTrim(`
25538
+ # USE SEARCH ENGINE
25539
+
25540
+ Enables the agent to use a search engine tool to access and retrieve up-to-date information from the internet.
25541
+
25542
+ ## Key aspects
25543
+
25544
+ - The content following \`USE SEARCH ENGINE\` is ignored (similar to NOTE)
25545
+ - The actual search engine tool usage is handled by the agent runtime
25546
+ - Allows the agent to search for current information from the web
25547
+ - Useful for research tasks, finding facts, and accessing dynamic content
25548
+
25549
+ ## Examples
25550
+
25551
+ \`\`\`book
25552
+ Research Assistant
25553
+
25554
+ PERSONA You are a helpful research assistant specialized in finding current information
25555
+ USE SEARCH ENGINE
25556
+ RULE Always cite your sources when providing information from the web
25557
+ \`\`\`
25558
+
25559
+ \`\`\`book
25560
+ Fact Checker
25561
+
25562
+ PERSONA You are a fact checker
25563
+ USE SEARCH ENGINE
25564
+ ACTION Search for claims and verify them against reliable sources
25565
+ \`\`\`
25566
+ `);
25567
+ }
25568
+ applyToAgentModelRequirements(requirements, content) {
25569
+ // We simply mark that search engine capability is enabled in metadata
25570
+ // Get existing metadata
25571
+ const existingMetadata = requirements.metadata || {};
25572
+ // Get existing tools array or create new one
25573
+ const existingTools = existingMetadata.tools || [];
25574
+ // Add 'search-engine' to tools if not already present
25575
+ const updatedTools = existingTools.includes('search-engine') ? existingTools : [...existingTools, 'search-engine'];
25576
+ // Return requirements with updated metadata
25577
+ return {
25578
+ ...requirements,
25579
+ metadata: {
25580
+ ...existingMetadata,
25581
+ tools: updatedTools,
25582
+ useSearchEngine: true,
25583
+ },
25584
+ };
25585
+ }
25586
+ }
25587
+ /**
25588
+ * Note: [💞] Ignore a discrepancy between file name and entity name
25589
+ */
25590
+
25591
+ /**
25592
+ * Placeholder commitment definition for commitments that are not yet implemented
25593
+ *
25594
+ * This commitment simply adds its content 1:1 into the system message,
25595
+ * preserving the original behavior until proper implementation is added.
25596
+ *
25597
+ * @public exported from `@promptbook/core`
25598
+ */
25599
+ class NotYetImplementedCommitmentDefinition extends BaseCommitmentDefinition {
25600
+ constructor(type) {
25601
+ super(type);
25602
+ }
25603
+ /**
25604
+ * Short one-line description of a placeholder commitment.
25605
+ */
25606
+ get description() {
25607
+ return 'Placeholder commitment that appends content verbatim to the system message.';
25608
+ }
25609
+ /**
25610
+ * Icon for this commitment.
25611
+ */
25612
+ get icon() {
25613
+ return '🚧';
25614
+ }
25615
+ /**
25616
+ * Markdown documentation available at runtime.
25617
+ */
25618
+ get documentation() {
25619
+ return spaceTrim$1.spaceTrim(`
25620
+ # ${this.type}
25621
+
25622
+ This commitment is not yet fully implemented.
25623
+
25624
+ ## Key aspects
25625
+
25626
+ - Content is appended directly to the system message.
25627
+ - No special processing or validation is performed.
25628
+ - Behavior preserved until proper implementation is added.
25629
+
25630
+ ## Status
25631
+
25632
+ - **Status:** Placeholder implementation
25633
+ - **Effect:** Appends content prefixed by commitment type
25634
+ - **Future:** Will be replaced with specialized logic
25635
+
25636
+ ## Examples
25637
+
25638
+ \`\`\`book
25639
+ Example Agent
25640
+
25641
+ PERSONA You are a helpful assistant
25642
+ ${this.type} Your content here
25643
+ RULE Always be helpful
25644
+ \`\`\`
25645
+ `);
25646
+ }
25647
+ applyToAgentModelRequirements(requirements, content) {
25648
+ const trimmedContent = content.trim();
25649
+ if (!trimmedContent) {
25650
+ return requirements;
25651
+ }
25652
+ // Add the commitment content 1:1 to the system message
25653
+ const commitmentLine = `${this.type} ${trimmedContent}`;
25654
+ return this.appendToSystemMessage(requirements, commitmentLine, '\n\n');
25655
+ }
25656
+ }
25657
+
25658
+ // Import all commitment definition classes
25659
+ /**
25660
+ * Registry of all available commitment definitions
25661
+ * This array contains instances of all commitment definitions
25662
+ * This is the single source of truth for all commitments in the system
25663
+ *
25664
+ * @private Use functions to access commitments instead of this array directly
25665
+ */
25666
+ const COMMITMENT_REGISTRY = [
25667
+ // Fully implemented commitments
25668
+ new PersonaCommitmentDefinition('PERSONA'),
25669
+ new PersonaCommitmentDefinition('PERSONAE'),
25670
+ new KnowledgeCommitmentDefinition(),
25671
+ new MemoryCommitmentDefinition('MEMORY'),
25672
+ new MemoryCommitmentDefinition('MEMORIES'),
25673
+ new StyleCommitmentDefinition('STYLE'),
25674
+ new StyleCommitmentDefinition('STYLES'),
25675
+ new RuleCommitmentDefinition('RULE'),
25676
+ new RuleCommitmentDefinition('RULES'),
25677
+ new LanguageCommitmentDefinition('LANGUAGE'),
25678
+ new LanguageCommitmentDefinition('LANGUAGES'),
25679
+ new SampleCommitmentDefinition('SAMPLE'),
25680
+ new SampleCommitmentDefinition('EXAMPLE'),
25681
+ new FormatCommitmentDefinition('FORMAT'),
25682
+ new FormatCommitmentDefinition('FORMATS'),
25683
+ new FromCommitmentDefinition('FROM'),
25684
+ new ModelCommitmentDefinition('MODEL'),
25685
+ new ModelCommitmentDefinition('MODELS'),
25686
+ new ActionCommitmentDefinition('ACTION'),
25687
+ new ActionCommitmentDefinition('ACTIONS'),
25688
+ new ComponentCommitmentDefinition(),
25689
+ new MetaImageCommitmentDefinition(),
25690
+ new MetaColorCommitmentDefinition(),
25691
+ new MetaFontCommitmentDefinition(),
25692
+ new MetaLinkCommitmentDefinition(),
25693
+ new MetaCommitmentDefinition(),
25694
+ new NoteCommitmentDefinition('NOTE'),
25695
+ new NoteCommitmentDefinition('NOTES'),
25696
+ new NoteCommitmentDefinition('COMMENT'),
25697
+ new NoteCommitmentDefinition('NONCE'),
25698
+ new GoalCommitmentDefinition('GOAL'),
25699
+ new GoalCommitmentDefinition('GOALS'),
25700
+ new InitialMessageCommitmentDefinition(),
25701
+ new UserMessageCommitmentDefinition(),
25702
+ new AgentMessageCommitmentDefinition(),
25703
+ new MessageCommitmentDefinition('MESSAGE'),
25704
+ new MessageCommitmentDefinition('MESSAGES'),
25705
+ new ScenarioCommitmentDefinition('SCENARIO'),
25706
+ new ScenarioCommitmentDefinition('SCENARIOS'),
25707
+ new DeleteCommitmentDefinition('DELETE'),
25708
+ new DeleteCommitmentDefinition('CANCEL'),
25709
+ new DeleteCommitmentDefinition('DISCARD'),
25710
+ new DeleteCommitmentDefinition('REMOVE'),
25711
+ new OpenCommitmentDefinition(),
25712
+ new ClosedCommitmentDefinition(),
25713
+ new UseBrowserCommitmentDefinition(),
25714
+ new UseSearchEngineCommitmentDefinition(),
25715
+ new UseMcpCommitmentDefinition(),
25716
+ new UseCommitmentDefinition(),
25717
+ // Not yet implemented commitments (using placeholder)
25718
+ new NotYetImplementedCommitmentDefinition('EXPECT'),
25719
+ new NotYetImplementedCommitmentDefinition('BEHAVIOUR'),
25720
+ new NotYetImplementedCommitmentDefinition('BEHAVIOURS'),
25721
+ new NotYetImplementedCommitmentDefinition('AVOID'),
25722
+ new NotYetImplementedCommitmentDefinition('AVOIDANCE'),
25723
+ new NotYetImplementedCommitmentDefinition('CONTEXT'),
25724
+ ];
25725
+ /**
25726
+ * Gets a commitment definition by its type
25727
+ * @param type The commitment type to look up
25728
+ * @returns The commitment definition or null if not found
25729
+ *
25730
+ * @public exported from `@promptbook/core`
25731
+ */
25732
+ function getCommitmentDefinition(type) {
25733
+ return COMMITMENT_REGISTRY.find((commitmentDefinition) => commitmentDefinition.type === type) || null;
25734
+ }
25735
+ /**
25736
+ * TODO: [🧠] Maybe create through standardized $register
25737
+ * Note: [💞] Ignore a discrepancy between file name and entity name
25738
+ */
25739
+
25740
+ /**
25741
+ * Creates an empty/basic agent model requirements object
25742
+ * This serves as the starting point for the reduce-like pattern
25743
+ * where each commitment applies its changes to build the final requirements
25744
+ *
25745
+ * @public exported from `@promptbook/core`
25746
+ */
25747
+ function createEmptyAgentModelRequirements() {
25748
+ return {
25749
+ systemMessage: '',
25750
+ // modelName: 'gpt-5',
25751
+ modelName: 'gemini-2.5-flash-lite',
25752
+ temperature: 0.7,
25753
+ topP: 0.9,
25754
+ topK: 50,
25755
+ };
25756
+ }
25757
+ /**
25758
+ * Creates a basic agent model requirements with just the agent name
25759
+ * This is used when we have an agent name but no commitments
25760
+ *
25761
+ * @public exported from `@promptbook/core`
25762
+ */
25763
+ function createBasicAgentModelRequirements(agentName) {
25764
+ const empty = createEmptyAgentModelRequirements();
25368
25765
  return {
25369
25766
  ...empty,
25370
25767
  systemMessage: `You are ${agentName || 'AI Agent'}`,
@@ -25374,6 +25771,11 @@
25374
25771
  * TODO: [🐤] Deduplicate `AgentModelRequirements` and `ModelRequirements` model requirements
25375
25772
  */
25376
25773
 
25774
+ /**
25775
+ * Regex pattern to match horizontal lines (markdown thematic breaks)
25776
+ * Matches 3 or more hyphens, underscores, or asterisks (with optional spaces between)
25777
+ */
25778
+ const HORIZONTAL_LINE_PATTERN = /^[\s]*[-_*][\s]*[-_*][\s]*[-_*][\s]*[-_*]*[\s]*$/;
25377
25779
  /**
25378
25780
  * Parses agent source using the new commitment system with multiline support
25379
25781
  * This function replaces the hardcoded commitment parsing in the original parseAgentSource
@@ -25416,7 +25818,7 @@
25416
25818
  const fullContent = currentCommitment.contentLines.join('\n');
25417
25819
  commitments.push({
25418
25820
  type: currentCommitment.type,
25419
- content: spaceTrim.spaceTrim(fullContent),
25821
+ content: spaceTrim$1.spaceTrim(fullContent),
25420
25822
  originalLine: currentCommitment.originalStartLine,
25421
25823
  lineNumber: currentCommitment.startLineNumber,
25422
25824
  });
@@ -25436,6 +25838,24 @@
25436
25838
  break;
25437
25839
  }
25438
25840
  }
25841
+ // Check if this is a horizontal line (ends any current commitment)
25842
+ const isHorizontalLine = HORIZONTAL_LINE_PATTERN.test(line);
25843
+ if (isHorizontalLine) {
25844
+ // Save the current commitment if it exists
25845
+ if (currentCommitment) {
25846
+ const fullContent = currentCommitment.contentLines.join('\n');
25847
+ commitments.push({
25848
+ type: currentCommitment.type,
25849
+ content: spaceTrim$1.spaceTrim(fullContent),
25850
+ originalLine: currentCommitment.originalStartLine,
25851
+ lineNumber: currentCommitment.startLineNumber,
25852
+ });
25853
+ currentCommitment = null;
25854
+ }
25855
+ // Add horizontal line to non-commitment lines
25856
+ nonCommitmentLines.push(line);
25857
+ continue;
25858
+ }
25439
25859
  if (!foundNewCommitment) {
25440
25860
  if (currentCommitment) {
25441
25861
  // This line belongs to the current commitment
@@ -25452,7 +25872,7 @@
25452
25872
  const fullContent = currentCommitment.contentLines.join('\n');
25453
25873
  commitments.push({
25454
25874
  type: currentCommitment.type,
25455
- content: spaceTrim.spaceTrim(fullContent),
25875
+ content: spaceTrim$1.spaceTrim(fullContent),
25456
25876
  originalLine: currentCommitment.originalStartLine,
25457
25877
  lineNumber: currentCommitment.startLineNumber,
25458
25878
  });
@@ -25763,6 +26183,10 @@
25763
26183
  meta.color = spaceTrim__default["default"](commitment.content);
25764
26184
  continue;
25765
26185
  }
26186
+ if (commitment.type === 'META FONT') {
26187
+ meta.font = spaceTrim__default["default"](commitment.content);
26188
+ continue;
26189
+ }
25766
26190
  if (commitment.type !== 'META') {
25767
26191
  continue;
25768
26192
  }