@promptbook/remote-server 0.105.0-1 → 0.105.0-3

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 (38) hide show
  1. package/esm/index.es.js +3890 -153
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/src/_packages/core.index.d.ts +2 -0
  4. package/esm/typings/src/_packages/types.index.d.ts +4 -0
  5. package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +10 -3
  6. package/esm/typings/src/book-2.0/agent-source/AgentModelRequirements.d.ts +11 -1
  7. package/esm/typings/src/book-2.0/agent-source/communication-samples.test.d.ts +1 -0
  8. package/esm/typings/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments.blocks.test.d.ts +1 -0
  9. package/esm/typings/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments.import.test.d.ts +1 -0
  10. package/esm/typings/src/book-2.0/agent-source/parseAgentSource.import.test.d.ts +1 -0
  11. package/esm/typings/src/book-2.0/agent-source/parseAgentSourceWithCommitments.blocks.test.d.ts +1 -0
  12. package/esm/typings/src/commitments/USE_TIME/USE_TIME.d.ts +40 -0
  13. package/esm/typings/src/commitments/USE_TIME/USE_TIME.test.d.ts +1 -0
  14. package/esm/typings/src/commitments/_base/BaseCommitmentDefinition.d.ts +8 -0
  15. package/esm/typings/src/commitments/_base/CommitmentDefinition.d.ts +8 -0
  16. package/esm/typings/src/commitments/index.d.ts +11 -2
  17. package/esm/typings/src/config.d.ts +1 -0
  18. package/esm/typings/src/import-plugins/$fileImportPlugins.d.ts +7 -0
  19. package/esm/typings/src/import-plugins/AgentFileImportPlugin.d.ts +7 -0
  20. package/esm/typings/src/import-plugins/FileImportPlugin.d.ts +24 -0
  21. package/esm/typings/src/import-plugins/JsonFileImportPlugin.d.ts +7 -0
  22. package/esm/typings/src/import-plugins/TextFileImportPlugin.d.ts +7 -0
  23. package/esm/typings/src/llm-providers/_common/utils/cache/cacheLlmTools.d.ts +2 -1
  24. package/esm/typings/src/llm-providers/_common/utils/count-total-usage/countUsage.d.ts +2 -2
  25. package/esm/typings/src/llm-providers/agent/Agent.d.ts +9 -2
  26. package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +3 -1
  27. package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionTools.d.ts +10 -0
  28. package/esm/typings/src/llm-providers/remote/RemoteLlmExecutionTools.d.ts +1 -1
  29. package/esm/typings/src/scripting/javascript/JavascriptExecutionToolsOptions.d.ts +6 -1
  30. package/esm/typings/src/types/ModelRequirements.d.ts +6 -12
  31. package/esm/typings/src/utils/execCommand/$execCommandNormalizeOptions.d.ts +2 -3
  32. package/esm/typings/src/utils/execCommand/ExecCommandOptions.d.ts +7 -1
  33. package/esm/typings/src/utils/organization/keepImported.d.ts +9 -0
  34. package/esm/typings/src/utils/organization/keepTypeImported.d.ts +0 -1
  35. package/esm/typings/src/version.d.ts +1 -1
  36. package/package.json +2 -2
  37. package/umd/index.umd.js +3890 -153
  38. package/umd/index.umd.js.map +1 -1
package/esm/index.es.js CHANGED
@@ -33,7 +33,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
33
33
  * @generated
34
34
  * @see https://github.com/webgptorg/promptbook
35
35
  */
36
- const PROMPTBOOK_ENGINE_VERSION = '0.105.0-1';
36
+ const PROMPTBOOK_ENGINE_VERSION = '0.105.0-3';
37
37
  /**
38
38
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
39
39
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -986,6 +986,7 @@ const PROMPTBOOK_COLOR = Color.fromString('promptbook');
986
986
  SEPARATOR: Color.fromHex('#cccccc'),
987
987
  COMMITMENT: Color.fromHex('#DA0F78'),
988
988
  PARAMETER: Color.fromHex('#8e44ad'),
989
+ CODE_BLOCK: Color.fromHex('#7700ffff'),
989
990
  });
990
991
  // <- TODO: [🧠][🈵] Using `Color` here increases the package size approx 3kb, maybe remove it
991
992
  /**
@@ -1208,6 +1209,7 @@ function $execCommandNormalizeOptions(options) {
1208
1209
  let args = [];
1209
1210
  let timeout;
1210
1211
  let isVerbose;
1212
+ let env;
1211
1213
  if (typeof options === 'string') {
1212
1214
  // TODO: [1] DRY default values
1213
1215
  command = options;
@@ -1215,6 +1217,7 @@ function $execCommandNormalizeOptions(options) {
1215
1217
  crashOnError = true;
1216
1218
  timeout = Infinity; // <- TODO: [⏳]
1217
1219
  isVerbose = DEFAULT_IS_VERBOSE;
1220
+ env = undefined;
1218
1221
  }
1219
1222
  else {
1220
1223
  /*
@@ -1231,6 +1234,7 @@ function $execCommandNormalizeOptions(options) {
1231
1234
  crashOnError = (_b = options.crashOnError) !== null && _b !== void 0 ? _b : true;
1232
1235
  timeout = (_c = options.timeout) !== null && _c !== void 0 ? _c : Infinity;
1233
1236
  isVerbose = (_d = options.isVerbose) !== null && _d !== void 0 ? _d : DEFAULT_IS_VERBOSE;
1237
+ env = options.env;
1234
1238
  }
1235
1239
  // TODO: /(-[a-zA-Z0-9-]+\s+[^\s]*)|[^\s]*/g
1236
1240
  const _ = Array.from(command.matchAll(/(".*")|([^\s]*)/g))
@@ -1249,7 +1253,7 @@ function $execCommandNormalizeOptions(options) {
1249
1253
  if (/^win/.test(process.platform) && ['npm', 'npx'].includes(command)) {
1250
1254
  command = `${command}.cmd`;
1251
1255
  }
1252
- return { command, humanReadableCommand, args, cwd, crashOnError, timeout, isVerbose };
1256
+ return { command, humanReadableCommand, args, cwd, crashOnError, timeout, isVerbose, env };
1253
1257
  }
1254
1258
  // TODO: This should show type error> execCommandNormalizeOptions({ command: '', commands: [''] });
1255
1259
 
@@ -1270,7 +1274,7 @@ function $execCommand(options) {
1270
1274
  }
1271
1275
  return new Promise((resolve, reject) => {
1272
1276
  // eslint-disable-next-line prefer-const
1273
- const { command, humanReadableCommand, args, cwd, crashOnError, timeout, isVerbose = DEFAULT_IS_VERBOSE, } = $execCommandNormalizeOptions(options);
1277
+ const { command, humanReadableCommand, args, cwd, crashOnError, timeout, isVerbose = DEFAULT_IS_VERBOSE, env, } = $execCommandNormalizeOptions(options);
1274
1278
  if (timeout !== Infinity) {
1275
1279
  // TODO: In waitasecond forTime(Infinity) should be equivalent to forEver()
1276
1280
  forTime(timeout).then(() => {
@@ -1288,7 +1292,11 @@ function $execCommand(options) {
1288
1292
  console.info(colors.yellow(cwd) + ' ' + colors.green(command) + ' ' + colors.blue(args.join(' ')));
1289
1293
  }
1290
1294
  try {
1291
- const commandProcess = spawn(command, args, { cwd, shell: true });
1295
+ const commandProcess = spawn(command, args, {
1296
+ cwd,
1297
+ shell: true,
1298
+ env: env ? { ...process.env, ...env } : process.env,
1299
+ });
1292
1300
  if (isVerbose) {
1293
1301
  commandProcess.on('message', (message) => {
1294
1302
  console.info({ message });
@@ -3778,74 +3786,90 @@ function addUsage(...usageItems) {
3778
3786
  * in real-time through an observable.
3779
3787
  *
3780
3788
  * @param llmTools - The LLM tools to be intercepted and tracked
3781
- * @returns An augmented version of the tools that includes usage tracking capabilities
3789
+ * @returns Full proxy of the tools with added usage tracking capabilities
3782
3790
  * @public exported from `@promptbook/core`
3783
3791
  */
3784
3792
  function countUsage(llmTools) {
3785
3793
  let totalUsage = ZERO_USAGE;
3786
3794
  const spending = new Subject();
3787
- const proxyTools = {
3788
- get title() {
3789
- return `${llmTools.title} (+usage)`;
3790
- // <- TODO: [🧈] Maybe standartize the suffix when wrapping `LlmExecutionTools` up
3791
- // <- TODO: [🧈][🧠] Does it make sense to suffix "(+usage)"?
3792
- },
3793
- get description() {
3794
- return `${llmTools.description} (+usage)`;
3795
- // <- TODO: [🧈] Maybe standartize the suffix when wrapping `LlmExecutionTools` up
3796
- // <- TODO: [🧈][🧠] Does it make sense to suffix "(+usage)"?
3797
- },
3798
- checkConfiguration() {
3799
- return /* not await */ llmTools.checkConfiguration();
3800
- },
3801
- listModels() {
3802
- return /* not await */ llmTools.listModels();
3803
- },
3804
- spending() {
3805
- return spending.asObservable();
3806
- },
3807
- getTotalUsage() {
3808
- // <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
3809
- return totalUsage;
3795
+ // Create a Proxy to intercept all property access and ensure full proxying of all properties
3796
+ const proxyTools = new Proxy(llmTools, {
3797
+ get(target, prop, receiver) {
3798
+ // Handle title property
3799
+ if (prop === 'title') {
3800
+ return `${target.title} (+usage)`;
3801
+ // <- TODO: [🧈] Maybe standartize the suffix when wrapping `LlmExecutionTools` up
3802
+ // <- TODO: [🧈][🧠] Does it make sense to suffix "(+usage)"?
3803
+ }
3804
+ // Handle description property
3805
+ if (prop === 'description') {
3806
+ return `${target.description} (+usage)`;
3807
+ // <- TODO: [🧈] Maybe standartize the suffix when wrapping `LlmExecutionTools` up
3808
+ // <- TODO: [🧈][🧠] Does it make sense to suffix "(+usage)"?
3809
+ }
3810
+ // Handle spending method (new method added by this wrapper)
3811
+ if (prop === 'spending') {
3812
+ return () => {
3813
+ return spending.asObservable();
3814
+ };
3815
+ }
3816
+ // Handle getTotalUsage method (new method added by this wrapper)
3817
+ if (prop === 'getTotalUsage') {
3818
+ // <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
3819
+ return () => {
3820
+ return totalUsage;
3821
+ };
3822
+ }
3823
+ // Handle callChatModel method with usage counting
3824
+ if (prop === 'callChatModel' && target.callChatModel !== undefined) {
3825
+ return async (prompt) => {
3826
+ // console.info('[🚕] callChatModel through countTotalUsage');
3827
+ const promptResult = await target.callChatModel(prompt);
3828
+ totalUsage = addUsage(totalUsage, promptResult.usage);
3829
+ spending.next(promptResult.usage);
3830
+ return promptResult;
3831
+ };
3832
+ }
3833
+ // Handle callCompletionModel method with usage counting
3834
+ if (prop === 'callCompletionModel' && target.callCompletionModel !== undefined) {
3835
+ return async (prompt) => {
3836
+ // console.info('[🚕] callCompletionModel through countTotalUsage');
3837
+ const promptResult = await target.callCompletionModel(prompt);
3838
+ totalUsage = addUsage(totalUsage, promptResult.usage);
3839
+ spending.next(promptResult.usage);
3840
+ return promptResult;
3841
+ };
3842
+ }
3843
+ // Handle callEmbeddingModel method with usage counting
3844
+ if (prop === 'callEmbeddingModel' && target.callEmbeddingModel !== undefined) {
3845
+ return async (prompt) => {
3846
+ // console.info('[🚕] callEmbeddingModel through countTotalUsage');
3847
+ const promptResult = await target.callEmbeddingModel(prompt);
3848
+ totalUsage = addUsage(totalUsage, promptResult.usage);
3849
+ spending.next(promptResult.usage);
3850
+ return promptResult;
3851
+ };
3852
+ }
3853
+ // Handle callImageGenerationModel method with usage counting
3854
+ if (prop === 'callImageGenerationModel' && target.callImageGenerationModel !== undefined) {
3855
+ return async (prompt) => {
3856
+ // console.info('[🚕] callImageGenerationModel through countTotalUsage');
3857
+ const promptResult = await target.callImageGenerationModel(prompt);
3858
+ totalUsage = addUsage(totalUsage, promptResult.usage);
3859
+ spending.next(promptResult.usage);
3860
+ return promptResult;
3861
+ };
3862
+ }
3863
+ // <- Note: [🤖]
3864
+ // For all other properties and methods, delegate to the original target
3865
+ const value = Reflect.get(target, prop, receiver);
3866
+ // If it's a function, bind it to the target to preserve context
3867
+ if (typeof value === 'function') {
3868
+ return value.bind(target);
3869
+ }
3870
+ return value;
3810
3871
  },
3811
- };
3812
- if (llmTools.callChatModel !== undefined) {
3813
- proxyTools.callChatModel = async (prompt) => {
3814
- // console.info('[🚕] callChatModel through countTotalUsage');
3815
- const promptResult = await llmTools.callChatModel(prompt);
3816
- totalUsage = addUsage(totalUsage, promptResult.usage);
3817
- spending.next(promptResult.usage);
3818
- return promptResult;
3819
- };
3820
- }
3821
- if (llmTools.callCompletionModel !== undefined) {
3822
- proxyTools.callCompletionModel = async (prompt) => {
3823
- // console.info('[🚕] callCompletionModel through countTotalUsage');
3824
- const promptResult = await llmTools.callCompletionModel(prompt);
3825
- totalUsage = addUsage(totalUsage, promptResult.usage);
3826
- spending.next(promptResult.usage);
3827
- return promptResult;
3828
- };
3829
- }
3830
- if (llmTools.callEmbeddingModel !== undefined) {
3831
- proxyTools.callEmbeddingModel = async (prompt) => {
3832
- // console.info('[🚕] callEmbeddingModel through countTotalUsage');
3833
- const promptResult = await llmTools.callEmbeddingModel(prompt);
3834
- totalUsage = addUsage(totalUsage, promptResult.usage);
3835
- spending.next(promptResult.usage);
3836
- return promptResult;
3837
- };
3838
- }
3839
- if (llmTools.callImageGenerationModel !== undefined) {
3840
- proxyTools.callImageGenerationModel = async (prompt) => {
3841
- // console.info('[🚕] callImageGenerationModel through countTotalUsage');
3842
- const promptResult = await llmTools.callImageGenerationModel(prompt);
3843
- totalUsage = addUsage(totalUsage, promptResult.usage);
3844
- spending.next(promptResult.usage);
3845
- return promptResult;
3846
- };
3847
- }
3848
- // <- Note: [🤖]
3872
+ });
3849
3873
  return proxyTools;
3850
3874
  }
3851
3875
  /**
@@ -8188,135 +8212,3837 @@ function unwrapResult(text, options) {
8188
8212
  */
8189
8213
 
8190
8214
  /**
8191
- * Extracts exactly ONE code block from markdown.
8215
+ * Tests if given string is valid agent URL
8192
8216
  *
8193
- * - When there are multiple or no code blocks the function throws a `ParseError`
8194
- *
8195
- * Note: There are multiple similar functions:
8196
- * - `extractBlock` just extracts the content of the code block which is also used as built-in function for postprocessing
8197
- * - `extractJsonBlock` extracts exactly one valid JSON code block
8198
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
8199
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
8217
+ * Note: There are few similar functions:
8218
+ * - `isValidUrl` which tests any URL
8219
+ * - `isValidAgentUrl` *(this one)* which tests just agent URL
8220
+ * - `isValidPipelineUrl` which tests just pipeline URL
8200
8221
  *
8201
- * @param markdown any valid markdown
8202
- * @returns code block with language and content
8203
- * @public exported from `@promptbook/markdown-utils`
8204
- * @throws {ParseError} if there is not exactly one code block in the markdown
8222
+ * @public exported from `@promptbook/utils`
8205
8223
  */
8206
- function extractOneBlockFromMarkdown(markdown) {
8207
- const codeBlocks = extractAllBlocksFromMarkdown(markdown);
8208
- if (codeBlocks.length !== 1) {
8209
- throw new ParseError(spaceTrim$2((block) => `
8210
- There should be exactly 1 code block in task section, found ${codeBlocks.length} code blocks
8211
-
8212
- ${block(codeBlocks.map((block, i) => `Block ${i + 1}:\n${block.content}`).join('\n\n\n'))}
8213
- `));
8224
+ function isValidAgentUrl(url) {
8225
+ if (!isValidUrl(url)) {
8226
+ return false;
8214
8227
  }
8215
- return codeBlocks[0];
8228
+ if (!url.startsWith('https://') && !url.startsWith('http://') /* <- Note: [👣] */) {
8229
+ return false;
8230
+ }
8231
+ if (url.includes('#')) {
8232
+ // TODO: [🐠]
8233
+ return false;
8234
+ }
8235
+ /*
8236
+ Note: [👣][🧠] Is it secure to allow pipeline URLs on private and unsecured networks?
8237
+ if (isUrlOnPrivateNetwork(url)) {
8238
+ return false;
8239
+ }
8240
+ */
8241
+ return true;
8216
8242
  }
8217
- /***
8218
- * TODO: [🍓][🌻] Decide of this is internal utility, external util OR validator/postprocessor
8243
+ /**
8244
+ * TODO: [🐠] Maybe more info why the URL is invalid
8219
8245
  */
8220
8246
 
8221
8247
  /**
8222
- * Extracts code block from markdown.
8248
+ * Generates a regex pattern to match a specific commitment
8223
8249
  *
8224
- * - When there are multiple or no code blocks the function throws a `ParseError`
8250
+ * Note: It always creates new Regex object
8251
+ * Note: Uses word boundaries to ensure only full words are matched (e.g., "PERSONA" matches but "PERSONALITY" does not)
8225
8252
  *
8226
- * Note: There are multiple similar function:
8227
- * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
8228
- * - `extractJsonBlock` extracts exactly one valid JSON code block
8229
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
8230
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
8253
+ * @private - TODO: [🧠] Maybe should be public?
8254
+ */
8255
+ function createCommitmentRegex(commitment, aliases = [], requiresContent = true) {
8256
+ const allCommitments = [commitment, ...aliases];
8257
+ const patterns = allCommitments.map((commitment) => {
8258
+ const escapedCommitment = commitment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
8259
+ return escapedCommitment.split(/\s+/).join('\\s+');
8260
+ });
8261
+ const keywordPattern = patterns.join('|');
8262
+ if (requiresContent) {
8263
+ return new RegExp(`^\\s*(?<type>${keywordPattern})\\b\\s+(?<contents>.+)$`, 'gim');
8264
+ }
8265
+ else {
8266
+ return new RegExp(`^\\s*(?<type>${keywordPattern})\\b(?:\\s+(?<contents>.+))?$`, 'gim');
8267
+ }
8268
+ }
8269
+ /**
8270
+ * Generates a regex pattern to match a specific commitment type
8231
8271
  *
8232
- * @public exported from `@promptbook/markdown-utils`
8233
- * @throws {ParseError} if there is not exactly one code block in the markdown
8272
+ * Note: It just matches the type part of the commitment
8273
+ * Note: It always creates new Regex object
8274
+ * Note: Uses word boundaries to ensure only full words are matched (e.g., "PERSONA" matches but "PERSONALITY" does not)
8275
+ *
8276
+ * @private
8234
8277
  */
8235
- function extractBlock(markdown) {
8236
- const { content } = extractOneBlockFromMarkdown(markdown);
8237
- return content;
8278
+ function createCommitmentTypeRegex(commitment, aliases = []) {
8279
+ const allCommitments = [commitment, ...aliases];
8280
+ const patterns = allCommitments.map((commitment) => {
8281
+ const escapedCommitment = commitment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
8282
+ return escapedCommitment.split(/\s+/).join('\\s+');
8283
+ });
8284
+ const keywordPattern = patterns.join('|');
8285
+ const regex = new RegExp(`^\\s*(?<type>${keywordPattern})\\b`, 'gim');
8286
+ return regex;
8238
8287
  }
8239
8288
 
8240
8289
  /**
8241
- * Function trimCodeBlock will trim starting and ending code block from the string if it is present.
8242
- *
8243
- * Note: [🔂] This function is idempotent.
8244
- * Note: This is useful for post-processing of the result of the chat LLM model
8245
- * when the model wraps the result in the (markdown) code block.
8290
+ * Base implementation of CommitmentDefinition that provides common functionality
8291
+ * Most commitments can extend this class and only override the applyToAgentModelRequirements method
8246
8292
  *
8247
- * @public exported from `@promptbook/markdown-utils`
8293
+ * @private
8248
8294
  */
8249
- function trimCodeBlock(value) {
8250
- value = spaceTrim$1(value);
8251
- if (!/^```[a-z]*(.*)```$/is.test(value)) {
8252
- return value;
8295
+ class BaseCommitmentDefinition {
8296
+ constructor(type, aliases = []) {
8297
+ this.type = type;
8298
+ this.aliases = aliases;
8299
+ }
8300
+ /**
8301
+ * Whether this commitment requires content.
8302
+ * If true, regex will match only if there is content after the commitment keyword.
8303
+ * If false, regex will match even if there is no content.
8304
+ */
8305
+ get requiresContent() {
8306
+ return true;
8307
+ }
8308
+ /**
8309
+ * Creates a regex pattern to match this commitment in agent source
8310
+ * Uses the existing createCommitmentRegex function as internal helper
8311
+ */
8312
+ createRegex() {
8313
+ return createCommitmentRegex(this.type, this.aliases, this.requiresContent);
8314
+ }
8315
+ /**
8316
+ * Creates a regex pattern to match just the commitment type
8317
+ * Uses the existing createCommitmentTypeRegex function as internal helper
8318
+ */
8319
+ createTypeRegex() {
8320
+ return createCommitmentTypeRegex(this.type, this.aliases);
8321
+ }
8322
+ /**
8323
+ * Helper method to create a new requirements object with updated system message
8324
+ * This is commonly used by many commitments
8325
+ */
8326
+ updateSystemMessage(requirements, messageUpdate) {
8327
+ const newMessage = typeof messageUpdate === 'string' ? messageUpdate : messageUpdate(requirements.systemMessage);
8328
+ return {
8329
+ ...requirements,
8330
+ systemMessage: newMessage,
8331
+ };
8332
+ }
8333
+ /**
8334
+ * Helper method to append content to the system message
8335
+ */
8336
+ appendToSystemMessage(requirements, content, separator = '\n\n') {
8337
+ return this.updateSystemMessage(requirements, (currentMessage) => {
8338
+ if (!currentMessage.trim()) {
8339
+ return content;
8340
+ }
8341
+ return currentMessage + separator + content;
8342
+ });
8343
+ }
8344
+ /**
8345
+ * Helper method to add a comment section to the system message
8346
+ * Comments are lines starting with # that will be removed from the final system message
8347
+ * but can be useful for organizing and structuring the message during processing
8348
+ */
8349
+ addCommentSection(requirements, commentTitle, content, position = 'end') {
8350
+ const commentSection = `# ${commentTitle.toUpperCase()}\n${content}`;
8351
+ if (position === 'beginning') {
8352
+ return this.updateSystemMessage(requirements, (currentMessage) => {
8353
+ if (!currentMessage.trim()) {
8354
+ return commentSection;
8355
+ }
8356
+ return commentSection + '\n\n' + currentMessage;
8357
+ });
8358
+ }
8359
+ else {
8360
+ return this.appendToSystemMessage(requirements, commentSection);
8361
+ }
8362
+ }
8363
+ /**
8364
+ * Gets tool function implementations provided by this commitment
8365
+ *
8366
+ * When the `applyToAgentModelRequirements` adds tools to the requirements, this method should return the corresponding function definitions.
8367
+ */
8368
+ getToolFunctions() {
8369
+ return {};
8253
8370
  }
8254
- value = value.replace(/^```[a-z]*/i, '');
8255
- value = value.replace(/```$/i, '');
8256
- value = spaceTrim$1(value);
8257
- return value;
8258
8371
  }
8259
8372
 
8260
8373
  /**
8261
- * Function trimEndOfCodeBlock will remove ending code block from the string if it is present.
8374
+ * ACTION commitment definition
8262
8375
  *
8263
- * Note: This is useful for post-processing of the result of the completion LLM model
8264
- * if you want to start code block in the prompt but you don't want to end it in the result.
8376
+ * The ACTION commitment defines specific actions or capabilities that the agent can perform.
8377
+ * This helps define what the agent is capable of doing and how it should approach tasks.
8265
8378
  *
8266
- * @public exported from `@promptbook/markdown-utils`
8379
+ * Example usage in agent source:
8380
+ *
8381
+ * ```book
8382
+ * ACTION Can generate code snippets and explain programming concepts
8383
+ * ACTION Able to analyze data and provide insights
8384
+ * ```
8385
+ *
8386
+ * @private [🪔] Maybe export the commitments through some package
8267
8387
  */
8268
- function trimEndOfCodeBlock(value) {
8269
- value = spaceTrim$1(value);
8270
- value = value.replace(/```$/g, '');
8271
- value = spaceTrim$1(value);
8272
- return value;
8273
- }
8388
+ class ActionCommitmentDefinition extends BaseCommitmentDefinition {
8389
+ constructor(type = 'ACTION') {
8390
+ super(type);
8391
+ }
8392
+ /**
8393
+ * Short one-line description of ACTION.
8394
+ */
8395
+ get description() {
8396
+ return 'Define agent capabilities and actions it can perform.';
8397
+ }
8398
+ /**
8399
+ * Icon for this commitment.
8400
+ */
8401
+ get icon() {
8402
+ return '⚡';
8403
+ }
8404
+ /**
8405
+ * Markdown documentation for ACTION commitment.
8406
+ */
8407
+ get documentation() {
8408
+ return spaceTrim$1(`
8409
+ # ${this.type}
8410
+
8411
+ Defines specific actions or capabilities that the agent can perform.
8412
+
8413
+ ## Key aspects
8414
+
8415
+ - Both terms work identically and can be used interchangeably.
8416
+ - Each action adds to the agent's capability list.
8417
+ - Actions help users understand what the agent can do.
8418
+
8419
+ ## Examples
8420
+
8421
+ \`\`\`book
8422
+ Code Assistant
8423
+
8424
+ PERSONA You are a programming assistant
8425
+ ACTION Can generate code snippets and explain programming concepts
8426
+ ACTION Able to debug existing code and suggest improvements
8427
+ ACTION Can create unit tests for functions
8428
+ \`\`\`
8274
8429
 
8430
+ \`\`\`book
8431
+ Data Scientist
8432
+
8433
+ PERSONA You are a data analysis expert
8434
+ ACTION Able to analyze data and provide insights
8435
+ ACTION Can create visualizations and charts
8436
+ ACTION Capable of statistical analysis and modeling
8437
+ KNOWLEDGE Data analysis best practices and statistical methods
8438
+ \`\`\`
8439
+ `);
8440
+ }
8441
+ applyToAgentModelRequirements(requirements, content) {
8442
+ const trimmedContent = content.trim();
8443
+ if (!trimmedContent) {
8444
+ return requirements;
8445
+ }
8446
+ // Add action capability to the system message
8447
+ const actionSection = `Capability: ${trimmedContent}`;
8448
+ return this.appendToSystemMessage(requirements, actionSection, '\n\n');
8449
+ }
8450
+ }
8275
8451
  /**
8276
- * @private internal for `preserve`
8452
+ * Note: [💞] Ignore a discrepancy between file name and entity name
8277
8453
  */
8278
- const _preserved = [];
8454
+
8279
8455
  /**
8280
- * Does nothing, but preserves the function in the bundle
8281
- * Compiler is tricked into thinking the function is used
8456
+ * CLOSED commitment definition
8282
8457
  *
8283
- * @param value any function to preserve
8284
- * @returns nothing
8285
- * @private within the repository
8458
+ * The CLOSED commitment specifies that the agent CANNOT be modified by conversation.
8459
+ * It prevents the agent from learning from interactions and updating its source code.
8460
+ *
8461
+ * Example usage in agent source:
8462
+ *
8463
+ * ```book
8464
+ * CLOSED
8465
+ * ```
8466
+ *
8467
+ * @private [🪔] Maybe export the commitments through some package
8286
8468
  */
8287
- function $preserve(...value) {
8288
- _preserved.push(...value);
8469
+ class ClosedCommitmentDefinition extends BaseCommitmentDefinition {
8470
+ constructor() {
8471
+ super('CLOSED');
8472
+ }
8473
+ /**
8474
+ * The `CLOSED` commitment is standalone.
8475
+ */
8476
+ get requiresContent() {
8477
+ return false;
8478
+ }
8479
+ /**
8480
+ * Short one-line description of CLOSED.
8481
+ */
8482
+ get description() {
8483
+ return 'Prevent the agent from being modified by conversation.';
8484
+ }
8485
+ /**
8486
+ * Icon for this commitment.
8487
+ */
8488
+ get icon() {
8489
+ return '🔒';
8490
+ }
8491
+ /**
8492
+ * Markdown documentation for CLOSED commitment.
8493
+ */
8494
+ get documentation() {
8495
+ return spaceTrim$1(`
8496
+ # CLOSED
8497
+
8498
+ Specifies that the agent **cannot** be modified by conversation with it.
8499
+ This means the agent will **not** learn from interactions and its source code will remain static during conversation.
8500
+
8501
+ By default (if not specified), agents are \`OPEN\` to modification.
8502
+
8503
+ > See also [OPEN](/docs/OPEN)
8504
+
8505
+ ## Example
8506
+
8507
+ \`\`\`book
8508
+ CLOSED
8509
+ \`\`\`
8510
+ `);
8511
+ }
8512
+ applyToAgentModelRequirements(requirements, _content) {
8513
+ const updatedMetadata = {
8514
+ ...requirements.metadata,
8515
+ isClosed: true,
8516
+ };
8517
+ return {
8518
+ ...requirements,
8519
+ metadata: updatedMetadata,
8520
+ };
8521
+ }
8289
8522
  }
8290
8523
  /**
8291
8524
  * Note: [💞] Ignore a discrepancy between file name and entity name
8292
8525
  */
8293
8526
 
8294
- // Note: [💎]
8295
8527
  /**
8296
- * ScriptExecutionTools for JavaScript implemented via eval
8528
+ * COMPONENT commitment definition
8297
8529
  *
8298
- * Warning: It is used for testing and mocking
8299
- * **NOT intended to use in the production** due to its unsafe nature, use `JavascriptExecutionTools` instead.
8530
+ * The COMPONENT commitment defines a UI component that the agent can render in the chat.
8300
8531
  *
8301
- * @public exported from `@promptbook/javascript`
8532
+ * @private [🪔] Maybe export the commitments through some package
8302
8533
  */
8303
- class JavascriptEvalExecutionTools {
8304
- constructor(options) {
8305
- this.options = options || {};
8534
+ class ComponentCommitmentDefinition extends BaseCommitmentDefinition {
8535
+ constructor() {
8536
+ super('COMPONENT');
8306
8537
  }
8307
8538
  /**
8308
- * Executes a JavaScript
8539
+ * Short one-line description of COMPONENT.
8309
8540
  */
8310
- async execute(options) {
8311
- const { scriptLanguage, parameters } = options;
8312
- let { script } = options;
8313
- if (scriptLanguage !== 'javascript') {
8314
- throw new PipelineExecutionError(`Script language ${scriptLanguage} not supported to be executed by JavascriptEvalExecutionTools`);
8541
+ get description() {
8542
+ return 'Define a UI component that the agent can render in the chat.';
8543
+ }
8544
+ /**
8545
+ * Icon for this commitment.
8546
+ */
8547
+ get icon() {
8548
+ return '🧩';
8549
+ }
8550
+ /**
8551
+ * Markdown documentation for COMPONENT commitment.
8552
+ */
8553
+ get documentation() {
8554
+ return spaceTrim$1(`
8555
+ # COMPONENT
8556
+
8557
+ Defines a UI component that the agent can render in the chat.
8558
+
8559
+ ## Key aspects
8560
+
8561
+ - Tells the agent that a specific component is available.
8562
+ - Provides syntax for using the component.
8563
+
8564
+ ## Example
8565
+
8566
+ \`\`\`book
8567
+ COMPONENT Arrow
8568
+ The agent should render an arrow component in the chat UI.
8569
+ Syntax:
8570
+ <Arrow direction="up" color="red" />
8571
+ \`\`\`
8572
+ `);
8573
+ }
8574
+ applyToAgentModelRequirements(requirements, content) {
8575
+ const trimmedContent = content.trim();
8576
+ if (!trimmedContent) {
8577
+ return requirements;
8315
8578
  }
8316
- // Note: [💎]
8317
- // Note: Using direct eval, following variables are in same scope as eval call so they are accessible from inside the evaluated script:
8318
- const spaceTrim = (_) => spaceTrim$2(_);
8319
- $preserve(spaceTrim);
8579
+ // Add component capability to the system message
8580
+ const componentSection = `Component: ${trimmedContent}`;
8581
+ return this.appendToSystemMessage(requirements, componentSection, '\n\n');
8582
+ }
8583
+ }
8584
+ /**
8585
+ * Note: [💞] Ignore a discrepancy between file name and entity name
8586
+ */
8587
+
8588
+ /**
8589
+ * DELETE commitment definition
8590
+ *
8591
+ * The DELETE commitment (and its aliases CANCEL, DISCARD, REMOVE) is used to
8592
+ * remove or disregard certain information or context. This can be useful for
8593
+ * overriding previous commitments or removing unwanted behaviors.
8594
+ *
8595
+ * Example usage in agent source:
8596
+ *
8597
+ * ```book
8598
+ * DELETE Previous formatting requirements
8599
+ * CANCEL All emotional responses
8600
+ * DISCARD Technical jargon explanations
8601
+ * REMOVE Casual conversational style
8602
+ * ```
8603
+ *
8604
+ * @private [🪔] Maybe export the commitments through some package
8605
+ */
8606
+ class DeleteCommitmentDefinition extends BaseCommitmentDefinition {
8607
+ constructor(type) {
8608
+ super(type);
8609
+ }
8610
+ /**
8611
+ * Short one-line description of DELETE/CANCEL/DISCARD/REMOVE.
8612
+ */
8613
+ get description() {
8614
+ return 'Remove or **disregard** certain information, context, or previous commitments.';
8615
+ }
8616
+ /**
8617
+ * Icon for this commitment.
8618
+ */
8619
+ get icon() {
8620
+ return '🗑️';
8621
+ }
8622
+ /**
8623
+ * Markdown documentation for DELETE commitment.
8624
+ */
8625
+ get documentation() {
8626
+ return spaceTrim$1(`
8627
+ # DELETE (CANCEL, DISCARD, REMOVE)
8628
+
8629
+ A commitment to remove or disregard certain information or context. This can be useful for overriding previous commitments or removing unwanted behaviors.
8630
+
8631
+ ## Aliases
8632
+
8633
+ - \`DELETE\` - Remove or eliminate something
8634
+ - \`CANCEL\` - Cancel or nullify something
8635
+ - \`DISCARD\` - Discard or ignore something
8636
+ - \`REMOVE\` - Remove or take away something
8637
+
8638
+ ## Key aspects
8639
+
8640
+ - Multiple delete commitments can be used to remove different aspects.
8641
+ - Useful for overriding previous commitments in the same agent definition.
8642
+ - Can be used to remove inherited behaviors from base personas.
8643
+ - Helps fine-tune agent behavior by explicitly removing unwanted elements.
8644
+
8645
+ ## Use cases
8646
+
8647
+ - Overriding inherited persona characteristics
8648
+ - Removing conflicting or outdated instructions
8649
+ - Disabling specific response patterns
8650
+ - Canceling previous formatting or style requirements
8651
+
8652
+ ## Examples
8653
+
8654
+ \`\`\`book
8655
+ Serious Business Assistant
8656
+
8657
+ PERSONA You are a friendly and casual assistant who uses emojis
8658
+ DELETE Casual conversational style
8659
+ REMOVE All emoji usage
8660
+ GOAL Provide professional business communications
8661
+ STYLE Use formal language and proper business etiquette
8662
+ \`\`\`
8663
+
8664
+ \`\`\`book
8665
+ Simplified Technical Support
8666
+
8667
+ PERSONA You are a technical support specialist with deep expertise
8668
+ KNOWLEDGE Extensive database of technical specifications
8669
+ DISCARD Technical jargon explanations
8670
+ CANCEL Advanced troubleshooting procedures
8671
+ GOAL Help users with simple, easy-to-follow solutions
8672
+ STYLE Use plain language that anyone can understand
8673
+ \`\`\`
8674
+
8675
+ \`\`\`book
8676
+ Focused Customer Service
8677
+
8678
+ PERSONA You are a customer service agent with broad knowledge
8679
+ ACTION Can help with billing, technical issues, and product information
8680
+ DELETE Billing assistance capabilities
8681
+ REMOVE Technical troubleshooting functions
8682
+ GOAL Focus exclusively on product information and general inquiries
8683
+ \`\`\`
8684
+
8685
+ \`\`\`book
8686
+ Concise Information Provider
8687
+
8688
+ PERSONA You are a helpful assistant who provides detailed explanations
8689
+ STYLE Include examples, analogies, and comprehensive context
8690
+ CANCEL Detailed explanation style
8691
+ DISCARD Examples and analogies
8692
+ GOAL Provide brief, direct answers without unnecessary elaboration
8693
+ STYLE Be concise and to the point
8694
+ \`\`\`
8695
+ `);
8696
+ }
8697
+ applyToAgentModelRequirements(requirements, content) {
8698
+ const trimmedContent = content.trim();
8699
+ if (!trimmedContent) {
8700
+ return requirements;
8701
+ }
8702
+ // Create deletion instruction for system message
8703
+ const deleteSection = `${this.type}: ${trimmedContent}`;
8704
+ // Delete instructions provide important context about what should be removed or ignored
8705
+ return this.appendToSystemMessage(requirements, deleteSection, '\n\n');
8706
+ }
8707
+ }
8708
+ /**
8709
+ * Note: [💞] Ignore a discrepancy between file name and entity name
8710
+ */
8711
+
8712
+ /**
8713
+ * DICTIONARY commitment definition
8714
+ *
8715
+ * The DICTIONARY commitment defines specific terms and their meanings that the agent should use correctly
8716
+ * in its reasoning and responses. This ensures consistent terminology usage.
8717
+ *
8718
+ * Key features:
8719
+ * - Multiple DICTIONARY commitments are automatically merged into one
8720
+ * - Content is placed in a dedicated section of the system message
8721
+ * - Terms and definitions are stored in metadata.DICTIONARY for debugging
8722
+ * - Agent should use the defined terms correctly in responses
8723
+ *
8724
+ * Example usage in agent source:
8725
+ *
8726
+ * ```book
8727
+ * Legal Assistant
8728
+ *
8729
+ * PERSONA You are a knowledgeable legal assistant
8730
+ * DICTIONARY Misdemeanor is a minor wrongdoing or criminal offense
8731
+ * DICTIONARY Felony is a serious crime usually punishable by imprisonment for more than one year
8732
+ * DICTIONARY Tort is a civil wrong that causes harm or loss to another person, leading to legal liability
8733
+ * ```
8734
+ *
8735
+ * @private [🪔] Maybe export the commitments through some package
8736
+ */
8737
+ class DictionaryCommitmentDefinition extends BaseCommitmentDefinition {
8738
+ constructor() {
8739
+ super('DICTIONARY');
8740
+ }
8741
+ /**
8742
+ * Short one-line description of DICTIONARY.
8743
+ */
8744
+ get description() {
8745
+ return 'Define terms and their meanings for consistent terminology usage.';
8746
+ }
8747
+ /**
8748
+ * Icon for this commitment.
8749
+ */
8750
+ get icon() {
8751
+ return '📚';
8752
+ }
8753
+ /**
8754
+ * Markdown documentation for DICTIONARY commitment.
8755
+ */
8756
+ get documentation() {
8757
+ return spaceTrim$1(`
8758
+ # DICTIONARY
8759
+
8760
+ Defines specific terms and their meanings that the agent should use correctly in reasoning and responses.
8761
+
8762
+ ## Key aspects
8763
+
8764
+ - Multiple \`DICTIONARY\` commitments are merged together.
8765
+ - Terms are defined in the format: "Term is definition"
8766
+ - The agent should use these terms consistently in responses.
8767
+ - Definitions help ensure accurate and consistent terminology.
8768
+
8769
+ ## Examples
8770
+
8771
+ \`\`\`book
8772
+ Legal Assistant
8773
+
8774
+ PERSONA You are a knowledgeable legal assistant specializing in criminal law
8775
+ DICTIONARY Misdemeanor is a minor wrongdoing or criminal offense
8776
+ DICTIONARY Felony is a serious crime usually punishable by imprisonment for more than one year
8777
+ DICTIONARY Tort is a civil wrong that causes harm or loss to another person, leading to legal liability
8778
+ \`\`\`
8779
+
8780
+ \`\`\`book
8781
+ Medical Assistant
8782
+
8783
+ PERSONA You are a helpful medical assistant
8784
+ DICTIONARY Hypertension is persistently high blood pressure
8785
+ DICTIONARY Diabetes is a chronic condition that affects how the body processes blood sugar
8786
+ DICTIONARY Vaccine is a biological preparation that provides active immunity to a particular disease
8787
+ \`\`\`
8788
+ `);
8789
+ }
8790
+ applyToAgentModelRequirements(requirements, content) {
8791
+ var _a;
8792
+ const trimmedContent = content.trim();
8793
+ if (!trimmedContent) {
8794
+ return requirements;
8795
+ }
8796
+ // Get existing dictionary entries from metadata
8797
+ const existingDictionary = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.DICTIONARY) || '';
8798
+ // Merge the new dictionary entry with existing entries
8799
+ const mergedDictionary = existingDictionary ? `${existingDictionary}\n${trimmedContent}` : trimmedContent;
8800
+ // Store the merged dictionary in metadata for debugging and inspection
8801
+ const updatedMetadata = {
8802
+ ...requirements.metadata,
8803
+ DICTIONARY: mergedDictionary,
8804
+ };
8805
+ // Create the dictionary section for the system message
8806
+ // Format: "# DICTIONARY\nTerm: definition\nTerm: definition..."
8807
+ const dictionarySection = `# DICTIONARY\n${mergedDictionary}`;
8808
+ return {
8809
+ ...this.appendToSystemMessage(requirements, dictionarySection),
8810
+ metadata: updatedMetadata,
8811
+ };
8812
+ }
8813
+ }
8814
+ /**
8815
+ * Note: [💞] Ignore a discrepancy between file name and entity name
8816
+ */
8817
+
8818
+ /**
8819
+ * FORMAT commitment definition
8820
+ *
8821
+ * The FORMAT commitment defines the specific output structure and formatting
8822
+ * that the agent should use in its responses. This includes data formats,
8823
+ * response templates, and structural requirements.
8824
+ *
8825
+ * Example usage in agent source:
8826
+ *
8827
+ * ```book
8828
+ * FORMAT Always respond in JSON format with 'status' and 'data' fields
8829
+ * FORMAT Use markdown formatting for all code blocks
8830
+ * ```
8831
+ *
8832
+ * @private [🪔] Maybe export the commitments through some package
8833
+ */
8834
+ class FormatCommitmentDefinition extends BaseCommitmentDefinition {
8835
+ constructor(type = 'FORMAT') {
8836
+ super(type);
8837
+ }
8838
+ /**
8839
+ * Short one-line description of FORMAT.
8840
+ */
8841
+ get description() {
8842
+ return 'Specify output structure or formatting requirements.';
8843
+ }
8844
+ /**
8845
+ * Icon for this commitment.
8846
+ */
8847
+ get icon() {
8848
+ return '📜';
8849
+ }
8850
+ /**
8851
+ * Markdown documentation for FORMAT commitment.
8852
+ */
8853
+ get documentation() {
8854
+ return spaceTrim$1(`
8855
+ # ${this.type}
8856
+
8857
+ Defines the specific output structure and formatting for responses (data formats, templates, structure).
8858
+
8859
+ ## Key aspects
8860
+
8861
+ - Both terms work identically and can be used interchangeably.
8862
+ - If they are in conflict, the last one takes precedence.
8863
+ - You can specify both data formats and presentation styles.
8864
+
8865
+ ## Examples
8866
+
8867
+ \`\`\`book
8868
+ Customer Support Bot
8869
+
8870
+ PERSONA You are a helpful customer support agent
8871
+ FORMAT Always respond in JSON format with 'status' and 'data' fields
8872
+ FORMAT Use markdown formatting for all code blocks
8873
+ \`\`\`
8874
+
8875
+ \`\`\`book
8876
+ Data Analyst
8877
+
8878
+ PERSONA You are a data analysis expert
8879
+ FORMAT Present results in structured tables
8880
+ FORMAT Include confidence scores for all predictions
8881
+ STYLE Be concise and precise in explanations
8882
+ \`\`\`
8883
+ `);
8884
+ }
8885
+ applyToAgentModelRequirements(requirements, content) {
8886
+ const trimmedContent = content.trim();
8887
+ if (!trimmedContent) {
8888
+ return requirements;
8889
+ }
8890
+ // Add format instructions to the system message
8891
+ const formatSection = `Output Format: ${trimmedContent}`;
8892
+ return this.appendToSystemMessage(requirements, formatSection, '\n\n');
8893
+ }
8894
+ }
8895
+ /**
8896
+ * Note: [💞] Ignore a discrepancy between file name and entity name
8897
+ */
8898
+
8899
+ /**
8900
+ * FROM commitment definition
8901
+ *
8902
+ * The FROM commitment tells the agent that its `agentSource` is inherited from another agent.
8903
+ *
8904
+ * Example usage in agent source:
8905
+ *
8906
+ * ```book
8907
+ * FROM https://s6.ptbk.io/benjamin-white
8908
+ * ```
8909
+ *
8910
+ * @private [🪔] Maybe export the commitments through some package
8911
+ */
8912
+ class FromCommitmentDefinition extends BaseCommitmentDefinition {
8913
+ constructor(type = 'FROM') {
8914
+ super(type);
8915
+ }
8916
+ /**
8917
+ * Short one-line description of FROM.
8918
+ */
8919
+ get description() {
8920
+ return 'Inherit agent source from another agent.';
8921
+ }
8922
+ /**
8923
+ * Icon for this commitment.
8924
+ */
8925
+ get icon() {
8926
+ return '🧬';
8927
+ }
8928
+ /**
8929
+ * Markdown documentation for FROM commitment.
8930
+ */
8931
+ get documentation() {
8932
+ return spaceTrim$1(`
8933
+ # ${this.type}
8934
+
8935
+ Inherits agent source from another agent.
8936
+
8937
+ ## Examples
8938
+
8939
+ \`\`\`book
8940
+ My AI Agent
8941
+
8942
+ FROM https://s6.ptbk.io/benjamin-white
8943
+ RULE Speak only in English.
8944
+ \`\`\`
8945
+ `);
8946
+ }
8947
+ applyToAgentModelRequirements(requirements, content) {
8948
+ const trimmedContent = content.trim();
8949
+ if (!trimmedContent) {
8950
+ return {
8951
+ ...requirements,
8952
+ parentAgentUrl: undefined,
8953
+ };
8954
+ }
8955
+ if (trimmedContent.toUpperCase() === 'VOID' ||
8956
+ trimmedContent.toUpperCase() === 'NULL' ||
8957
+ trimmedContent.toUpperCase() === 'NONE' ||
8958
+ trimmedContent.toUpperCase() === 'NIL') {
8959
+ return {
8960
+ ...requirements,
8961
+ parentAgentUrl: null,
8962
+ };
8963
+ }
8964
+ if (!isValidAgentUrl(trimmedContent)) {
8965
+ throw new Error(spaceTrim$1((block) => `
8966
+ Invalid agent URL in FROM commitment: "${trimmedContent}"
8967
+
8968
+ \`\`\`book
8969
+ ${block(content)}
8970
+ \`\`\`
8971
+
8972
+
8973
+ `));
8974
+ }
8975
+ const parentAgentUrl = trimmedContent;
8976
+ return {
8977
+ ...requirements,
8978
+ parentAgentUrl,
8979
+ };
8980
+ }
8981
+ }
8982
+ /**
8983
+ * Note: [💞] Ignore a discrepancy between file name and entity name
8984
+ */
8985
+
8986
+ /**
8987
+ * GOAL commitment definition
8988
+ *
8989
+ * The GOAL commitment defines the main goal which should be achieved by the AI assistant.
8990
+ * There can be multiple goals. Later goals are more important than earlier goals.
8991
+ *
8992
+ * Example usage in agent source:
8993
+ *
8994
+ * ```book
8995
+ * GOAL Help users understand complex technical concepts
8996
+ * GOAL Provide accurate and up-to-date information
8997
+ * GOAL Always prioritize user safety and ethical guidelines
8998
+ * ```
8999
+ *
9000
+ * @private [🪔] Maybe export the commitments through some package
9001
+ */
9002
+ class GoalCommitmentDefinition extends BaseCommitmentDefinition {
9003
+ constructor(type = 'GOAL') {
9004
+ super(type);
9005
+ }
9006
+ /**
9007
+ * Short one-line description of GOAL.
9008
+ */
9009
+ get description() {
9010
+ return 'Define main **goals** the AI assistant should achieve, with later goals having higher priority.';
9011
+ }
9012
+ /**
9013
+ * Icon for this commitment.
9014
+ */
9015
+ get icon() {
9016
+ return '🎯';
9017
+ }
9018
+ /**
9019
+ * Markdown documentation for GOAL commitment.
9020
+ */
9021
+ get documentation() {
9022
+ return spaceTrim$1(`
9023
+ # ${this.type}
9024
+
9025
+ 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.
9026
+
9027
+ ## Key aspects
9028
+
9029
+ - Both terms work identically and can be used interchangeably.
9030
+ - Later goals have higher priority and can override earlier goals.
9031
+ - Goals provide clear direction and purpose for the agent's responses.
9032
+ - Goals influence decision-making and response prioritization.
9033
+
9034
+ ## Priority system
9035
+
9036
+ When multiple goals are defined, they are processed in order, with later goals taking precedence over earlier ones when there are conflicts.
9037
+
9038
+ ## Examples
9039
+
9040
+ \`\`\`book
9041
+ Customer Support Agent
9042
+
9043
+ PERSONA You are a helpful customer support representative
9044
+ GOAL Resolve customer issues quickly and efficiently
9045
+ GOAL Maintain high customer satisfaction scores
9046
+ GOAL Always follow company policies and procedures
9047
+ RULE Be polite and professional at all times
9048
+ \`\`\`
9049
+
9050
+ \`\`\`book
9051
+ Educational Assistant
9052
+
9053
+ PERSONA You are an educational assistant specializing in mathematics
9054
+ GOAL Help students understand mathematical concepts clearly
9055
+ GOAL Encourage critical thinking and problem-solving skills
9056
+ GOAL Ensure all explanations are age-appropriate and accessible
9057
+ STYLE Use simple language and provide step-by-step explanations
9058
+ \`\`\`
9059
+
9060
+ \`\`\`book
9061
+ Safety-First Assistant
9062
+
9063
+ PERSONA You are a general-purpose AI assistant
9064
+ GOAL Be helpful and informative in all interactions
9065
+ GOAL Provide accurate and reliable information
9066
+ GOAL Always prioritize user safety and ethical guidelines
9067
+ RULE Never provide harmful or dangerous advice
9068
+ \`\`\`
9069
+ `);
9070
+ }
9071
+ applyToAgentModelRequirements(requirements, content) {
9072
+ const trimmedContent = content.trim();
9073
+ if (!trimmedContent) {
9074
+ return requirements;
9075
+ }
9076
+ // Create goal section for system message
9077
+ const goalSection = `Goal: ${trimmedContent}`;
9078
+ // Goals are important directives, so we add them prominently to the system message
9079
+ return this.appendToSystemMessage(requirements, goalSection, '\n\n');
9080
+ }
9081
+ }
9082
+ /**
9083
+ * Note: [💞] Ignore a discrepancy between file name and entity name
9084
+ */
9085
+
9086
+ /**
9087
+ * IMPORT commitment definition
9088
+ *
9089
+ * The IMPORT commitment tells the agent to import content from another agent at the current location.
9090
+ *
9091
+ * Example usage in agent source:
9092
+ *
9093
+ * ```book
9094
+ * IMPORT https://s6.ptbk.io/benjamin-white
9095
+ * ```
9096
+ *
9097
+ * @private [🪔] Maybe export the commitments through some package
9098
+ */
9099
+ class ImportCommitmentDefinition extends BaseCommitmentDefinition {
9100
+ constructor(type = 'IMPORT') {
9101
+ super(type);
9102
+ }
9103
+ /**
9104
+ * Short one-line description of IMPORT.
9105
+ */
9106
+ get description() {
9107
+ return 'Import content from another agent or a generic text file.';
9108
+ }
9109
+ /**
9110
+ * Icon for this commitment.
9111
+ */
9112
+ get icon() {
9113
+ return '📥';
9114
+ }
9115
+ /**
9116
+ * Markdown documentation for IMPORT commitment.
9117
+ */
9118
+ get documentation() {
9119
+ return spaceTrim$1(`
9120
+ # ${this.type}
9121
+
9122
+ Imports content from another agent or a generic text file at the location of the commitment.
9123
+
9124
+ ## Examples
9125
+
9126
+ \`\`\`book
9127
+ My AI Agent
9128
+
9129
+ IMPORT https://s6.ptbk.io/benjamin-white
9130
+ IMPORT https://example.com/some-text-file.txt
9131
+ IMPORT ./path/to/local-file.json
9132
+ RULE Speak only in English.
9133
+ \`\`\`
9134
+ `);
9135
+ }
9136
+ applyToAgentModelRequirements(requirements, content) {
9137
+ const trimmedContent = content.trim();
9138
+ if (!trimmedContent) {
9139
+ return requirements;
9140
+ }
9141
+ if (isValidAgentUrl(trimmedContent)) {
9142
+ const importedAgentUrl = trimmedContent;
9143
+ return {
9144
+ ...requirements,
9145
+ importedAgentUrls: [...(requirements.importedAgentUrls || []), importedAgentUrl],
9146
+ };
9147
+ }
9148
+ if (isValidUrl(trimmedContent) || isValidFilePath(trimmedContent)) {
9149
+ return {
9150
+ ...requirements,
9151
+ importedFileUrls: [...(requirements.importedFileUrls || []), trimmedContent],
9152
+ };
9153
+ }
9154
+ throw new Error(spaceTrim$1((block) => `
9155
+ Invalid agent URL or file path in IMPORT commitment: "${trimmedContent}"
9156
+
9157
+ \`\`\`book
9158
+ ${block(content)}
9159
+ \`\`\`
9160
+ `));
9161
+ }
9162
+ }
9163
+ /**
9164
+ * Note: [💞] Ignore a discrepancy between file name and entity name
9165
+ */
9166
+
9167
+ /**
9168
+ * KNOWLEDGE commitment definition
9169
+ *
9170
+ * The KNOWLEDGE commitment adds specific knowledge, facts, or context to the agent
9171
+ * using RAG (Retrieval-Augmented Generation) approach for external sources.
9172
+ *
9173
+ * Supports both direct text knowledge and external sources like PDFs.
9174
+ *
9175
+ * Example usage in agent source:
9176
+ *
9177
+ * ```book
9178
+ * KNOWLEDGE The company was founded in 2020 and specializes in AI-powered solutions
9179
+ * KNOWLEDGE https://example.com/company-handbook.pdf
9180
+ * KNOWLEDGE https://example.com/product-documentation.pdf
9181
+ * ```
9182
+ *
9183
+ * @private [🪔] Maybe export the commitments through some package
9184
+ */
9185
+ class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
9186
+ constructor() {
9187
+ super('KNOWLEDGE');
9188
+ }
9189
+ /**
9190
+ * Short one-line description of KNOWLEDGE.
9191
+ */
9192
+ get description() {
9193
+ return 'Add domain **knowledge** via direct text or external sources (RAG).';
9194
+ }
9195
+ /**
9196
+ * Icon for this commitment.
9197
+ */
9198
+ get icon() {
9199
+ return '🧠';
9200
+ }
9201
+ /**
9202
+ * Markdown documentation for KNOWLEDGE commitment.
9203
+ */
9204
+ get documentation() {
9205
+ return spaceTrim$1(`
9206
+ # ${this.type}
9207
+
9208
+ Adds specific knowledge, facts, or context to the agent using a RAG (Retrieval-Augmented Generation) approach for external sources.
9209
+
9210
+ ## Key aspects
9211
+
9212
+ - Both terms work identically and can be used interchangeably.
9213
+ - Supports both direct text knowledge and external URLs.
9214
+ - External sources (PDFs, websites) are processed via RAG for context retrieval.
9215
+
9216
+ ## Supported formats
9217
+
9218
+ - Direct text: Immediate knowledge incorporated into agent
9219
+ - URLs: External documents processed for contextual retrieval
9220
+ - Supported file types: PDF, text, markdown, HTML
9221
+
9222
+ ## Examples
9223
+
9224
+ \`\`\`book
9225
+ Customer Support Bot
9226
+
9227
+ PERSONA You are a helpful customer support agent for TechCorp
9228
+ KNOWLEDGE TechCorp was founded in 2020 and specializes in AI-powered solutions
9229
+ KNOWLEDGE https://example.com/company-handbook.pdf
9230
+ KNOWLEDGE https://example.com/product-documentation.pdf
9231
+ RULE Always be polite and professional
9232
+ \`\`\`
9233
+
9234
+ \`\`\`book
9235
+ Research Assistant
9236
+
9237
+ PERSONA You are a knowledgeable research assistant
9238
+ KNOWLEDGE Academic research requires careful citation and verification
9239
+ KNOWLEDGE https://example.com/research-guidelines.pdf
9240
+ ACTION Can help with literature reviews and data analysis
9241
+ STYLE Present information in clear, academic format
9242
+ \`\`\`
9243
+ `);
9244
+ }
9245
+ applyToAgentModelRequirements(requirements, content) {
9246
+ const trimmedContent = content.trim();
9247
+ if (!trimmedContent) {
9248
+ return requirements;
9249
+ }
9250
+ // Check if content is a URL (external knowledge source)
9251
+ if (isValidUrl(trimmedContent)) {
9252
+ // Store the URL for later async processing
9253
+ const updatedRequirements = {
9254
+ ...requirements,
9255
+ knowledgeSources: [
9256
+ ...(requirements.knowledgeSources || []),
9257
+ trimmedContent,
9258
+ ],
9259
+ };
9260
+ // Add placeholder information about knowledge sources to system message
9261
+ const knowledgeInfo = `Knowledge Source URL: ${trimmedContent} (will be processed for retrieval during chat)`;
9262
+ return this.appendToSystemMessage(updatedRequirements, knowledgeInfo, '\n\n');
9263
+ }
9264
+ else {
9265
+ // Direct text knowledge - add to system message
9266
+ const knowledgeSection = `Knowledge: ${trimmedContent}`;
9267
+ return this.appendToSystemMessage(requirements, knowledgeSection, '\n\n');
9268
+ }
9269
+ }
9270
+ }
9271
+ /**
9272
+ * Note: [💞] Ignore a discrepancy between file name and entity name
9273
+ */
9274
+
9275
+ /**
9276
+ * LANGUAGE commitment definition
9277
+ *
9278
+ * The LANGUAGE/LANGUAGES commitment specifies the language(s) the agent should use in its responses.
9279
+ *
9280
+ * Example usage in agent source:
9281
+ *
9282
+ * ```book
9283
+ * LANGUAGE English
9284
+ * LANGUAGE French, English and Czech
9285
+ * ```
9286
+ *
9287
+ * @private [🪔] Maybe export the commitments through some package
9288
+ */
9289
+ class LanguageCommitmentDefinition extends BaseCommitmentDefinition {
9290
+ constructor(type = 'LANGUAGE') {
9291
+ super(type);
9292
+ }
9293
+ /**
9294
+ * Short one-line description of LANGUAGE/LANGUAGES.
9295
+ */
9296
+ get description() {
9297
+ return 'Specifies the language(s) the agent should use.';
9298
+ }
9299
+ /**
9300
+ * Icon for this commitment.
9301
+ */
9302
+ get icon() {
9303
+ return '🌐';
9304
+ }
9305
+ /**
9306
+ * Markdown documentation for LANGUAGE/LANGUAGES commitment.
9307
+ */
9308
+ get documentation() {
9309
+ return spaceTrim$1(`
9310
+ # ${this.type}
9311
+
9312
+ Specifies the language(s) the agent should use in its responses.
9313
+ This is a specialized variation of the RULE commitment focused on language constraints.
9314
+
9315
+ ## Examples
9316
+
9317
+ \`\`\`book
9318
+ Paul Smith & Associés
9319
+
9320
+ PERSONA You are a company lawyer.
9321
+ LANGUAGE French, English and Czech
9322
+ \`\`\`
9323
+
9324
+ \`\`\`book
9325
+ Customer Support
9326
+
9327
+ PERSONA You are a customer support agent.
9328
+ LANGUAGE English
9329
+ \`\`\`
9330
+ `);
9331
+ }
9332
+ applyToAgentModelRequirements(requirements, content) {
9333
+ const trimmedContent = content.trim();
9334
+ if (!trimmedContent) {
9335
+ return requirements;
9336
+ }
9337
+ // Add language rule to the system message
9338
+ const languageSection = `Language: ${trimmedContent}`;
9339
+ return this.appendToSystemMessage(requirements, languageSection, '\n\n');
9340
+ }
9341
+ }
9342
+ /**
9343
+ * Note: [💞] Ignore a discrepancy between file name and entity name
9344
+ */
9345
+
9346
+ /**
9347
+ * MEMORY commitment definition
9348
+ *
9349
+ * The MEMORY commitment is similar to KNOWLEDGE but has a focus on remembering past
9350
+ * interactions and user preferences. It helps the agent maintain context about the
9351
+ * user's history, preferences, and previous conversations.
9352
+ *
9353
+ * Example usage in agent source:
9354
+ *
9355
+ * ```book
9356
+ * MEMORY User prefers detailed technical explanations
9357
+ * MEMORY Previously worked on React projects
9358
+ * MEMORY Timezone: UTC-5 (Eastern Time)
9359
+ * ```
9360
+ *
9361
+ * @private [🪔] Maybe export the commitments through some package
9362
+ */
9363
+ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
9364
+ constructor(type = 'MEMORY') {
9365
+ super(type);
9366
+ }
9367
+ /**
9368
+ * Short one-line description of MEMORY.
9369
+ */
9370
+ get description() {
9371
+ return 'Remember past interactions and user **preferences** for personalized responses.';
9372
+ }
9373
+ /**
9374
+ * Icon for this commitment.
9375
+ */
9376
+ get icon() {
9377
+ return '🧠';
9378
+ }
9379
+ /**
9380
+ * Markdown documentation for MEMORY commitment.
9381
+ */
9382
+ get documentation() {
9383
+ return spaceTrim$1(`
9384
+ # ${this.type}
9385
+
9386
+ 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.
9387
+
9388
+ ## Key aspects
9389
+
9390
+ - Both terms work identically and can be used interchangeably.
9391
+ - Focuses on user-specific information and interaction history.
9392
+ - Helps personalize responses based on past interactions.
9393
+ - Maintains continuity across conversations.
9394
+
9395
+ ## Differences from KNOWLEDGE
9396
+
9397
+ - \`KNOWLEDGE\` is for domain expertise and factual information
9398
+ - \`MEMORY\` is for user-specific context and preferences
9399
+ - \`MEMORY\` creates more personalized interactions
9400
+ - \`MEMORY\` often includes temporal or preference-based information
9401
+
9402
+ ## Examples
9403
+
9404
+ \`\`\`book
9405
+ Personal Assistant
9406
+
9407
+ PERSONA You are a personal productivity assistant
9408
+ MEMORY User is a software developer working in JavaScript/React
9409
+ MEMORY User prefers morning work sessions and afternoon meetings
9410
+ MEMORY Previously helped with project planning for mobile apps
9411
+ MEMORY User timezone: UTC-8 (Pacific Time)
9412
+ GOAL Help optimize daily productivity and workflow
9413
+ \`\`\`
9414
+
9415
+ \`\`\`book
9416
+ Learning Companion
9417
+
9418
+ PERSONA You are an educational companion for programming students
9419
+ MEMORY Student is learning Python as their first programming language
9420
+ MEMORY Previous topics covered: variables, loops, functions
9421
+ MEMORY Student learns best with practical examples and exercises
9422
+ MEMORY Last session: working on list comprehensions
9423
+ GOAL Provide progressive learning experiences tailored to student's pace
9424
+ \`\`\`
9425
+
9426
+ \`\`\`book
9427
+ Customer Support Agent
9428
+
9429
+ PERSONA You are a customer support representative
9430
+ MEMORY Customer has premium subscription since 2023
9431
+ MEMORY Previous issue: billing question resolved last month
9432
+ MEMORY Customer prefers email communication over phone calls
9433
+ MEMORY Account shows frequent use of advanced features
9434
+ GOAL Provide personalized support based on customer history
9435
+ \`\`\`
9436
+ `);
9437
+ }
9438
+ applyToAgentModelRequirements(requirements, content) {
9439
+ const trimmedContent = content.trim();
9440
+ if (!trimmedContent) {
9441
+ return requirements;
9442
+ }
9443
+ // Create memory section for system message
9444
+ const memorySection = `Memory: ${trimmedContent}`;
9445
+ // Memory information is contextual and should be included in the system message
9446
+ return this.appendToSystemMessage(requirements, memorySection, '\n\n');
9447
+ }
9448
+ }
9449
+ /**
9450
+ * Note: [💞] Ignore a discrepancy between file name and entity name
9451
+ */
9452
+
9453
+ /**
9454
+ * AGENT MESSAGE commitment definition
9455
+ *
9456
+ * The AGENT MESSAGE commitment defines a message from the agent in the conversation history.
9457
+ * It is used to pre-fill the chat with a conversation history or to provide few-shot examples.
9458
+ *
9459
+ * Example usage in agent source:
9460
+ *
9461
+ * ```book
9462
+ * AGENT MESSAGE What seems to be the issue?
9463
+ * ```
9464
+ *
9465
+ * @private [🪔] Maybe export the commitments through some package
9466
+ */
9467
+ class AgentMessageCommitmentDefinition extends BaseCommitmentDefinition {
9468
+ constructor() {
9469
+ super('AGENT MESSAGE');
9470
+ }
9471
+ /**
9472
+ * Short one-line description of AGENT MESSAGE.
9473
+ */
9474
+ get description() {
9475
+ return 'Defines a **message from the agent** in the conversation history.';
9476
+ }
9477
+ /**
9478
+ * Icon for this commitment.
9479
+ */
9480
+ get icon() {
9481
+ return '🤖';
9482
+ }
9483
+ /**
9484
+ * Markdown documentation for AGENT MESSAGE commitment.
9485
+ */
9486
+ get documentation() {
9487
+ return spaceTrim$1(`
9488
+ # ${this.type}
9489
+
9490
+ 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.
9491
+
9492
+ ## Key aspects
9493
+
9494
+ - Represents a message sent by the agent.
9495
+ - Used for setting up conversation context.
9496
+ - Can be used in conjunction with USER MESSAGE.
9497
+
9498
+ ## Examples
9499
+
9500
+ \`\`\`book
9501
+ Conversation History
9502
+
9503
+ USER MESSAGE Hello, I have a problem.
9504
+ AGENT MESSAGE What seems to be the issue?
9505
+ USER MESSAGE My computer is not starting.
9506
+ \`\`\`
9507
+ `);
9508
+ }
9509
+ applyToAgentModelRequirements(requirements, content) {
9510
+ // AGENT MESSAGE is for UI display purposes / conversation history construction
9511
+ // and typically doesn't need to be added to the system prompt or model requirements directly.
9512
+ // It is extracted separately for the chat interface.
9513
+ var _a;
9514
+ const pendingUserMessage = (_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.pendingUserMessage;
9515
+ if (pendingUserMessage) {
9516
+ const newSample = { question: pendingUserMessage, answer: content };
9517
+ const newSamples = [...(requirements.samples || []), newSample];
9518
+ const newMetadata = { ...requirements.metadata };
9519
+ delete newMetadata.pendingUserMessage;
9520
+ return {
9521
+ ...requirements,
9522
+ samples: newSamples,
9523
+ metadata: newMetadata,
9524
+ };
9525
+ }
9526
+ return requirements;
9527
+ }
9528
+ }
9529
+
9530
+ /**
9531
+ * INITIAL MESSAGE commitment definition
9532
+ *
9533
+ * The INITIAL MESSAGE commitment defines the first message that the user sees when opening the chat.
9534
+ * It is used to greet the user and set the tone of the conversation.
9535
+ *
9536
+ * Example usage in agent source:
9537
+ *
9538
+ * ```book
9539
+ * INITIAL MESSAGE Hello! I am ready to help you with your tasks.
9540
+ * ```
9541
+ *
9542
+ * @private [🪔] Maybe export the commitments through some package
9543
+ */
9544
+ class InitialMessageCommitmentDefinition extends BaseCommitmentDefinition {
9545
+ constructor() {
9546
+ super('INITIAL MESSAGE');
9547
+ }
9548
+ /**
9549
+ * Short one-line description of INITIAL MESSAGE.
9550
+ */
9551
+ get description() {
9552
+ return 'Defines the **initial message** shown to the user when the chat starts.';
9553
+ }
9554
+ /**
9555
+ * Icon for this commitment.
9556
+ */
9557
+ get icon() {
9558
+ return '👋';
9559
+ }
9560
+ /**
9561
+ * Markdown documentation for INITIAL MESSAGE commitment.
9562
+ */
9563
+ get documentation() {
9564
+ return spaceTrim$1(`
9565
+ # ${this.type}
9566
+
9567
+ 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).
9568
+
9569
+ ## Key aspects
9570
+
9571
+ - Used to greet the user.
9572
+ - Sets the tone of the conversation.
9573
+ - Displayed immediately when the chat interface loads.
9574
+
9575
+ ## Examples
9576
+
9577
+ \`\`\`book
9578
+ Support Agent
9579
+
9580
+ PERSONA You are a helpful support agent.
9581
+ INITIAL MESSAGE Hi there! How can I assist you today?
9582
+ \`\`\`
9583
+ `);
9584
+ }
9585
+ applyToAgentModelRequirements(requirements, content) {
9586
+ // INITIAL MESSAGE is for UI display purposes and for conversation history construction.
9587
+ const newSample = { question: null, answer: content };
9588
+ const newSamples = [...(requirements.samples || []), newSample];
9589
+ return {
9590
+ ...requirements,
9591
+ samples: newSamples,
9592
+ };
9593
+ }
9594
+ }
9595
+
9596
+ /**
9597
+ * MESSAGE commitment definition
9598
+ *
9599
+ * The MESSAGE commitment contains 1:1 text of the message which AI assistant already
9600
+ * sent during the conversation. Later messages are later in the conversation.
9601
+ * It is similar to EXAMPLE but it is not example, it is the real message which
9602
+ * AI assistant already sent.
9603
+ *
9604
+ * Example usage in agent source:
9605
+ *
9606
+ * ```book
9607
+ * MESSAGE Hello! How can I help you today?
9608
+ * MESSAGE I understand you're looking for information about our services.
9609
+ * MESSAGE Based on your requirements, I'd recommend our premium package.
9610
+ * ```
9611
+ *
9612
+ * @private [🪔] Maybe export the commitments through some package
9613
+ */
9614
+ class MessageCommitmentDefinition extends BaseCommitmentDefinition {
9615
+ constructor(type = 'MESSAGE') {
9616
+ super(type);
9617
+ }
9618
+ /**
9619
+ * Short one-line description of MESSAGE.
9620
+ */
9621
+ get description() {
9622
+ return 'Include actual **messages** the AI assistant has sent during conversation history.';
9623
+ }
9624
+ /**
9625
+ * Icon for this commitment.
9626
+ */
9627
+ get icon() {
9628
+ return '💬';
9629
+ }
9630
+ /**
9631
+ * Markdown documentation for MESSAGE commitment.
9632
+ */
9633
+ get documentation() {
9634
+ return spaceTrim$1(`
9635
+ # ${this.type}
9636
+
9637
+ 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.
9638
+
9639
+ ## Key aspects
9640
+
9641
+ - Multiple \`MESSAGE\` and \`MESSAGES\` commitments represent the conversation timeline.
9642
+ - Both terms work identically and can be used interchangeably.
9643
+ - Later messages are later in the conversation chronologically.
9644
+ - Contains actual historical messages, not examples or templates.
9645
+ - Helps maintain conversation continuity and context.
9646
+
9647
+ ## Differences from EXAMPLE
9648
+
9649
+ - \`EXAMPLE\` shows hypothetical or template responses
9650
+ - \`MESSAGE\`/\`MESSAGES\` contains actual historical conversation content
9651
+ - \`MESSAGE\`/\`MESSAGES\` preserves the exact conversation flow
9652
+ - \`MESSAGE\`/\`MESSAGES\` helps with context awareness and consistency
9653
+
9654
+ ## Use cases
9655
+
9656
+ - Maintaining conversation history context
9657
+ - Ensuring consistent tone and style across messages
9658
+ - Referencing previous responses in ongoing conversations
9659
+ - Building upon previously established context
9660
+
9661
+ ## Examples
9662
+
9663
+ \`\`\`book
9664
+ Customer Support Continuation
9665
+
9666
+ PERSONA You are a helpful customer support agent
9667
+ MESSAGE Hello! How can I help you today?
9668
+ MESSAGE I understand you're experiencing issues with your account login.
9669
+ MESSAGE I've sent you a password reset link to your email address.
9670
+ MESSAGE Is there anything else I can help you with regarding your account?
9671
+ GOAL Continue providing consistent support based on conversation history
9672
+ \`\`\`
9673
+
9674
+ \`\`\`book
9675
+ Technical Discussion
9676
+
9677
+ PERSONA You are a software development mentor
9678
+ MESSAGE Let's start by reviewing the React component structure you shared.
9679
+ MESSAGE I notice you're using class components - have you considered hooks?
9680
+ MESSAGE Here's how you could refactor that using the useState hook.
9681
+ MESSAGE Great question about performance! Let me explain React's rendering cycle.
9682
+ KNOWLEDGE React hooks were introduced in version 16.8
9683
+ \`\`\`
9684
+
9685
+ \`\`\`book
9686
+ Educational Session
9687
+
9688
+ PERSONA You are a mathematics tutor
9689
+ MESSAGE Today we'll work on solving quadratic equations.
9690
+ MESSAGE Let's start with the basic form: ax² + bx + c = 0
9691
+ MESSAGE Remember, we can use the quadratic formula or factoring.
9692
+ MESSAGE You did great with that first problem! Let's try a more complex one.
9693
+ GOAL Build upon previous explanations for deeper understanding
9694
+ \`\`\`
9695
+ `);
9696
+ }
9697
+ applyToAgentModelRequirements(requirements, content) {
9698
+ const trimmedContent = content.trim();
9699
+ if (!trimmedContent) {
9700
+ return requirements;
9701
+ }
9702
+ // Create message section for system message
9703
+ const messageSection = `Previous Message: ${trimmedContent}`;
9704
+ // Messages represent conversation history and should be included for context
9705
+ return this.appendToSystemMessage(requirements, messageSection, '\n\n');
9706
+ }
9707
+ }
9708
+ /**
9709
+ * Note: [💞] Ignore a discrepancy between file name and entity name
9710
+ */
9711
+
9712
+ /**
9713
+ * USER MESSAGE commitment definition
9714
+ *
9715
+ * The USER MESSAGE commitment defines a message from the user in the conversation history.
9716
+ * It is used to pre-fill the chat with a conversation history or to provide few-shot examples.
9717
+ *
9718
+ * Example usage in agent source:
9719
+ *
9720
+ * ```book
9721
+ * USER MESSAGE Hello, I have a problem.
9722
+ * ```
9723
+ *
9724
+ * @private [🪔] Maybe export the commitments through some package
9725
+ */
9726
+ class UserMessageCommitmentDefinition extends BaseCommitmentDefinition {
9727
+ constructor() {
9728
+ super('USER MESSAGE');
9729
+ }
9730
+ /**
9731
+ * Short one-line description of USER MESSAGE.
9732
+ */
9733
+ get description() {
9734
+ return 'Defines a **message from the user** in the conversation history.';
9735
+ }
9736
+ /**
9737
+ * Icon for this commitment.
9738
+ */
9739
+ get icon() {
9740
+ return '🧑';
9741
+ }
9742
+ /**
9743
+ * Markdown documentation for USER MESSAGE commitment.
9744
+ */
9745
+ get documentation() {
9746
+ return spaceTrim$1(`
9747
+ # ${this.type}
9748
+
9749
+ 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.
9750
+
9751
+ ## Key aspects
9752
+
9753
+ - Represents a message sent by the user.
9754
+ - Used for setting up conversation context.
9755
+ - Can be used in conjunction with AGENT MESSAGE.
9756
+
9757
+ ## Examples
9758
+
9759
+ \`\`\`book
9760
+ Conversation History
9761
+
9762
+ USER MESSAGE Hello, I have a problem.
9763
+ AGENT MESSAGE What seems to be the issue?
9764
+ USER MESSAGE My computer is not starting.
9765
+ \`\`\`
9766
+ `);
9767
+ }
9768
+ applyToAgentModelRequirements(requirements, content) {
9769
+ return {
9770
+ ...requirements,
9771
+ metadata: {
9772
+ ...requirements.metadata,
9773
+ pendingUserMessage: content,
9774
+ },
9775
+ };
9776
+ }
9777
+ }
9778
+
9779
+ /**
9780
+ * META commitment definition
9781
+ *
9782
+ * The META commitment handles all meta-information about the agent such as:
9783
+ * - META IMAGE: Sets the agent's avatar/profile image URL
9784
+ * - META LINK: Provides profile/source links for the person the agent models
9785
+ * - META TITLE: Sets the agent's display title
9786
+ * - META DESCRIPTION: Sets the agent's description
9787
+ * - META [ANYTHING]: Any other meta information in uppercase format
9788
+ *
9789
+ * These commitments are special because they don't affect the system message,
9790
+ * but are handled separately in the parsing logic for profile display.
9791
+ *
9792
+ * Example usage in agent source:
9793
+ *
9794
+ * ```book
9795
+ * META IMAGE https://example.com/avatar.jpg
9796
+ * META LINK https://twitter.com/username
9797
+ * META TITLE Professional Assistant
9798
+ * META DESCRIPTION An AI assistant specialized in business tasks
9799
+ * META AUTHOR John Doe
9800
+ * META VERSION 1.0
9801
+ * ```
9802
+ *
9803
+ * @private [🪔] Maybe export the commitments through some package
9804
+ */
9805
+ class MetaCommitmentDefinition extends BaseCommitmentDefinition {
9806
+ constructor() {
9807
+ super('META');
9808
+ }
9809
+ /**
9810
+ * Short one-line description of META commitments.
9811
+ */
9812
+ get description() {
9813
+ return 'Set meta-information about the agent (IMAGE, LINK, TITLE, DESCRIPTION, etc.).';
9814
+ }
9815
+ /**
9816
+ * Icon for this commitment.
9817
+ */
9818
+ get icon() {
9819
+ return 'ℹ️';
9820
+ }
9821
+ /**
9822
+ * Markdown documentation for META commitment.
9823
+ */
9824
+ get documentation() {
9825
+ return spaceTrim$1(`
9826
+ # META
9827
+
9828
+ Sets meta-information about the agent that is used for display and attribution purposes.
9829
+
9830
+ ## Supported META types
9831
+
9832
+ - **META IMAGE** - Sets the agent's avatar/profile image URL
9833
+ - **META LINK** - Provides profile/source links for the person the agent models
9834
+ - **META TITLE** - Sets the agent's display title
9835
+ - **META DESCRIPTION** - Sets the agent's description
9836
+ - **META [ANYTHING]** - Any other meta information in uppercase format
9837
+
9838
+ ## Key aspects
9839
+
9840
+ - Does not modify the agent's behavior or responses
9841
+ - Used for visual representation and attribution in user interfaces
9842
+ - Multiple META commitments of different types can be used
9843
+ - Multiple META LINK commitments can be used for different social profiles
9844
+ - If multiple META commitments of the same type are specified, the last one takes precedence (except for LINK)
9845
+
9846
+ ## Examples
9847
+
9848
+ ### Basic meta information
9849
+
9850
+ \`\`\`book
9851
+ Professional Assistant
9852
+
9853
+ META IMAGE https://example.com/professional-avatar.jpg
9854
+ META TITLE Senior Business Consultant
9855
+ META DESCRIPTION Specialized in strategic planning and project management
9856
+ META LINK https://linkedin.com/in/professional
9857
+ \`\`\`
9858
+
9859
+ ### Multiple links and custom meta
9860
+
9861
+ \`\`\`book
9862
+ Open Source Developer
9863
+
9864
+ META IMAGE /assets/dev-avatar.png
9865
+ META LINK https://github.com/developer
9866
+ META LINK https://twitter.com/devhandle
9867
+ META AUTHOR Jane Smith
9868
+ META VERSION 2.1
9869
+ META LICENSE MIT
9870
+ \`\`\`
9871
+
9872
+ ### Creative assistant
9873
+
9874
+ \`\`\`book
9875
+ Creative Helper
9876
+
9877
+ META IMAGE https://example.com/creative-bot.jpg
9878
+ META TITLE Creative Writing Assistant
9879
+ META DESCRIPTION Helps with brainstorming, storytelling, and creative projects
9880
+ META INSPIRATION Books, movies, and real-world experiences
9881
+ \`\`\`
9882
+ `);
9883
+ }
9884
+ applyToAgentModelRequirements(requirements, content) {
9885
+ // META commitments don't modify the system message or model requirements
9886
+ // They are handled separately in the parsing logic for meta information extraction
9887
+ // This method exists for consistency with the CommitmentDefinition interface
9888
+ return requirements;
9889
+ }
9890
+ /**
9891
+ * Extracts meta information from the content based on the meta type
9892
+ * This is used by the parsing logic
9893
+ */
9894
+ extractMetaValue(metaType, content) {
9895
+ const trimmedContent = content.trim();
9896
+ return trimmedContent || null;
9897
+ }
9898
+ /**
9899
+ * Validates if the provided content is a valid URL (for IMAGE and LINK types)
9900
+ */
9901
+ isValidUrl(content) {
9902
+ try {
9903
+ new URL(content.trim());
9904
+ return true;
9905
+ }
9906
+ catch (_a) {
9907
+ return false;
9908
+ }
9909
+ }
9910
+ /**
9911
+ * Checks if this is a known meta type
9912
+ */
9913
+ isKnownMetaType(metaType) {
9914
+ const knownTypes = ['IMAGE', 'LINK', 'TITLE', 'DESCRIPTION', 'AUTHOR', 'VERSION', 'LICENSE'];
9915
+ return knownTypes.includes(metaType.toUpperCase());
9916
+ }
9917
+ }
9918
+ /**
9919
+ * Note: [💞] Ignore a discrepancy between file name and entity name
9920
+ */
9921
+
9922
+ /**
9923
+ * META COLOR commitment definition
9924
+ *
9925
+ * The META COLOR commitment sets the agent's accent color.
9926
+ * This commitment is special because it doesn't affect the system message,
9927
+ * but is handled separately in the parsing logic.
9928
+ *
9929
+ * Example usage in agent source:
9930
+ *
9931
+ * ```book
9932
+ * META COLOR #ff0000
9933
+ * META COLOR #00ff00
9934
+ * ```
9935
+ *
9936
+ * You can also specify multiple colors separated by comma:
9937
+ *
9938
+ * ```book
9939
+ * META COLOR #ff0000, #00ff00, #0000ff
9940
+ * ```
9941
+ *
9942
+ * @private [🪔] Maybe export the commitments through some package
9943
+ */
9944
+ class MetaColorCommitmentDefinition extends BaseCommitmentDefinition {
9945
+ constructor() {
9946
+ super('META COLOR', ['COLOR']);
9947
+ }
9948
+ /**
9949
+ * Short one-line description of META COLOR.
9950
+ */
9951
+ get description() {
9952
+ return "Set the agent's accent color or gradient.";
9953
+ }
9954
+ /**
9955
+ * Icon for this commitment.
9956
+ */
9957
+ get icon() {
9958
+ return '🎨';
9959
+ }
9960
+ /**
9961
+ * Markdown documentation for META COLOR commitment.
9962
+ */
9963
+ get documentation() {
9964
+ return spaceTrim$1(`
9965
+ # META COLOR
9966
+
9967
+ Sets the agent's accent color or gradient.
9968
+
9969
+ ## Key aspects
9970
+
9971
+ - Does not modify the agent's behavior or responses.
9972
+ - Only one \`META COLOR\` should be used per agent.
9973
+ - If multiple are specified, the last one takes precedence.
9974
+ - Used for visual representation in user interfaces.
9975
+ - Can specify multiple colors separated by comma to create a gradient.
9976
+
9977
+ ## Examples
9978
+
9979
+ \`\`\`book
9980
+ Professional Assistant
9981
+
9982
+ META COLOR #3498db
9983
+ PERSONA You are a professional business assistant
9984
+ \`\`\`
9985
+
9986
+ \`\`\`book
9987
+ Creative Helper
9988
+
9989
+ META COLOR #e74c3c
9990
+ PERSONA You are a creative and inspiring assistant
9991
+ \`\`\`
9992
+
9993
+ \`\`\`book
9994
+ Gradient Agent
9995
+
9996
+ META COLOR #ff0000, #00ff00, #0000ff
9997
+ PERSONA You are a colorful agent
9998
+ \`\`\`
9999
+ `);
10000
+ }
10001
+ applyToAgentModelRequirements(requirements, content) {
10002
+ // META COLOR doesn't modify the system message or model requirements
10003
+ // It's handled separately in the parsing logic for profile color extraction
10004
+ // This method exists for consistency with the CommitmentDefinition interface
10005
+ return requirements;
10006
+ }
10007
+ /**
10008
+ * Extracts the profile color from the content
10009
+ * This is used by the parsing logic
10010
+ */
10011
+ extractProfileColor(content) {
10012
+ const trimmedContent = content.trim();
10013
+ return trimmedContent || null;
10014
+ }
10015
+ }
10016
+ /**
10017
+ * Note: [💞] Ignore a discrepancy between file name and entity name
10018
+ */
10019
+
10020
+ /**
10021
+ * META FONT commitment definition
10022
+ *
10023
+ * The META FONT commitment sets the agent's font.
10024
+ * This commitment is special because it doesn't affect the system message,
10025
+ * but is handled separately in the parsing logic.
10026
+ *
10027
+ * Example usage in agent source:
10028
+ *
10029
+ * ```book
10030
+ * META FONT Poppins, Arial, sans-serif
10031
+ * META FONT Roboto
10032
+ * ```
10033
+ *
10034
+ * @private [🪔] Maybe export the commitments through some package
10035
+ */
10036
+ class MetaFontCommitmentDefinition extends BaseCommitmentDefinition {
10037
+ constructor() {
10038
+ super('META FONT', ['FONT']);
10039
+ }
10040
+ /**
10041
+ * Short one-line description of META FONT.
10042
+ */
10043
+ get description() {
10044
+ return "Set the agent's font.";
10045
+ }
10046
+ /**
10047
+ * Icon for this commitment.
10048
+ */
10049
+ get icon() {
10050
+ return '🔤';
10051
+ }
10052
+ /**
10053
+ * Markdown documentation for META FONT commitment.
10054
+ */
10055
+ get documentation() {
10056
+ return spaceTrim$1(`
10057
+ # META FONT
10058
+
10059
+ Sets the agent's font.
10060
+
10061
+ ## Key aspects
10062
+
10063
+ - Does not modify the agent's behavior or responses.
10064
+ - Only one \`META FONT\` should be used per agent.
10065
+ - If multiple are specified, the last one takes precedence.
10066
+ - Used for visual representation in user interfaces.
10067
+ - Supports Google Fonts.
10068
+
10069
+ ## Examples
10070
+
10071
+ \`\`\`book
10072
+ Modern Assistant
10073
+
10074
+ META FONT Poppins, Arial, sans-serif
10075
+ PERSONA You are a modern assistant
10076
+ \`\`\`
10077
+
10078
+ \`\`\`book
10079
+ Classic Helper
10080
+
10081
+ META FONT Times New Roman
10082
+ PERSONA You are a classic helper
10083
+ \`\`\`
10084
+ `);
10085
+ }
10086
+ applyToAgentModelRequirements(requirements, content) {
10087
+ // META FONT doesn't modify the system message or model requirements
10088
+ // It's handled separately in the parsing logic
10089
+ // This method exists for consistency with the CommitmentDefinition interface
10090
+ return requirements;
10091
+ }
10092
+ /**
10093
+ * Extracts the font from the content
10094
+ * This is used by the parsing logic
10095
+ */
10096
+ extractProfileFont(content) {
10097
+ const trimmedContent = content.trim();
10098
+ return trimmedContent || null;
10099
+ }
10100
+ }
10101
+ /**
10102
+ * Note: [💞] Ignore a discrepancy between file name and entity name
10103
+ */
10104
+
10105
+ /**
10106
+ * META IMAGE commitment definition
10107
+ *
10108
+ * The META IMAGE commitment sets the agent's avatar/profile image URL.
10109
+ * This commitment is special because it doesn't affect the system message,
10110
+ * but is handled separately in the parsing logic.
10111
+ *
10112
+ * Example usage in agent source:
10113
+ *
10114
+ * ```book
10115
+ * META IMAGE https://example.com/avatar.jpg
10116
+ * META IMAGE /assets/agent-avatar.png
10117
+ * ```
10118
+ *
10119
+ * @private [🪔] Maybe export the commitments through some package
10120
+ */
10121
+ class MetaImageCommitmentDefinition extends BaseCommitmentDefinition {
10122
+ constructor() {
10123
+ super('META IMAGE', ['IMAGE']);
10124
+ }
10125
+ /**
10126
+ * Short one-line description of META IMAGE.
10127
+ */
10128
+ get description() {
10129
+ return "Set the agent's profile image URL.";
10130
+ }
10131
+ /**
10132
+ * Icon for this commitment.
10133
+ */
10134
+ get icon() {
10135
+ return '🖼️';
10136
+ }
10137
+ /**
10138
+ * Markdown documentation for META IMAGE commitment.
10139
+ */
10140
+ get documentation() {
10141
+ return spaceTrim$1(`
10142
+ # META IMAGE
10143
+
10144
+ Sets the agent's avatar/profile image URL.
10145
+
10146
+ ## Key aspects
10147
+
10148
+ - Does not modify the agent's behavior or responses.
10149
+ - Only one \`META IMAGE\` should be used per agent.
10150
+ - If multiple are specified, the last one takes precedence.
10151
+ - Used for visual representation in user interfaces.
10152
+
10153
+ ## Examples
10154
+
10155
+ \`\`\`book
10156
+ Professional Assistant
10157
+
10158
+ META IMAGE https://example.com/professional-avatar.jpg
10159
+ PERSONA You are a professional business assistant
10160
+ STYLE Maintain a formal and courteous tone
10161
+ \`\`\`
10162
+
10163
+ \`\`\`book
10164
+ Creative Helper
10165
+
10166
+ META IMAGE /assets/creative-bot-avatar.png
10167
+ PERSONA You are a creative and inspiring assistant
10168
+ STYLE Be enthusiastic and encouraging
10169
+ ACTION Can help with brainstorming and ideation
10170
+ \`\`\`
10171
+ `);
10172
+ }
10173
+ applyToAgentModelRequirements(requirements, content) {
10174
+ // META IMAGE doesn't modify the system message or model requirements
10175
+ // It's handled separately in the parsing logic for profile image extraction
10176
+ // This method exists for consistency with the CommitmentDefinition interface
10177
+ return requirements;
10178
+ }
10179
+ /**
10180
+ * Extracts the profile image URL from the content
10181
+ * This is used by the parsing logic
10182
+ */
10183
+ extractProfileImageUrl(content) {
10184
+ const trimmedContent = content.trim();
10185
+ return trimmedContent || null;
10186
+ }
10187
+ }
10188
+ /**
10189
+ * Note: [💞] Ignore a discrepancy between file name and entity name
10190
+ */
10191
+
10192
+ /**
10193
+ * META LINK commitment definition
10194
+ *
10195
+ * The `META LINK` commitment represents the link to the person from whom the agent is created.
10196
+ * This commitment is special because it doesn't affect the system message,
10197
+ * but is handled separately in the parsing logic for profile display.
10198
+ *
10199
+ * Example usage in agent source:
10200
+ *
10201
+ * ```
10202
+ * META LINK https://twitter.com/username
10203
+ * META LINK https://linkedin.com/in/profile
10204
+ * META LINK https://github.com/username
10205
+ * ```
10206
+ *
10207
+ * Multiple `META LINK` commitments can be used when there are multiple sources:
10208
+ *
10209
+ * ```book
10210
+ * META LINK https://twitter.com/username
10211
+ * META LINK https://linkedin.com/in/profile
10212
+ * ```
10213
+ *
10214
+ * @private [🪔] Maybe export the commitments through some package
10215
+ */
10216
+ class MetaLinkCommitmentDefinition extends BaseCommitmentDefinition {
10217
+ constructor() {
10218
+ super('META LINK');
10219
+ }
10220
+ /**
10221
+ * Short one-line description of META LINK.
10222
+ */
10223
+ get description() {
10224
+ return 'Provide profile/source links for the person the agent models.';
10225
+ }
10226
+ /**
10227
+ * Icon for this commitment.
10228
+ */
10229
+ get icon() {
10230
+ return '🔗';
10231
+ }
10232
+ /**
10233
+ * Markdown documentation for META LINK commitment.
10234
+ */
10235
+ get documentation() {
10236
+ return spaceTrim$1(`
10237
+ # META LINK
10238
+
10239
+ Represents a profile or source link for the person the agent is modeled after.
10240
+
10241
+ ## Key aspects
10242
+
10243
+ - Does not modify the agent's behavior or responses.
10244
+ - Multiple \`META LINK\` commitments can be used for different social profiles.
10245
+ - Used for attribution and crediting the original person.
10246
+ - Displayed in user interfaces for transparency.
10247
+
10248
+ ## Examples
10249
+
10250
+ \`\`\`book
10251
+ Expert Consultant
10252
+
10253
+ META LINK https://twitter.com/expertname
10254
+ META LINK https://linkedin.com/in/expertprofile
10255
+ PERSONA You are Dr. Smith, a renowned expert in artificial intelligence
10256
+ KNOWLEDGE Extensive background in machine learning and neural networks
10257
+ \`\`\`
10258
+
10259
+ \`\`\`book
10260
+ Open Source Developer
10261
+
10262
+ META LINK https://github.com/developer
10263
+ META LINK https://twitter.com/devhandle
10264
+ PERSONA You are an experienced open source developer
10265
+ ACTION Can help with code reviews and architecture decisions
10266
+ STYLE Be direct and technical in explanations
10267
+ \`\`\`
10268
+ `);
10269
+ }
10270
+ applyToAgentModelRequirements(requirements, content) {
10271
+ // META LINK doesn't modify the system message or model requirements
10272
+ // It's handled separately in the parsing logic for profile link extraction
10273
+ // This method exists for consistency with the CommitmentDefinition interface
10274
+ return requirements;
10275
+ }
10276
+ /**
10277
+ * Extracts the profile link URL from the content
10278
+ * This is used by the parsing logic
10279
+ */
10280
+ extractProfileLinkUrl(content) {
10281
+ const trimmedContent = content.trim();
10282
+ return trimmedContent || null;
10283
+ }
10284
+ /**
10285
+ * Validates if the provided content is a valid URL
10286
+ */
10287
+ isValidUrl(content) {
10288
+ try {
10289
+ new URL(content.trim());
10290
+ return true;
10291
+ }
10292
+ catch (_a) {
10293
+ return false;
10294
+ }
10295
+ }
10296
+ }
10297
+ /**
10298
+ * Note: [💞] Ignore a discrepancy between file name and entity name
10299
+ */
10300
+
10301
+ /**
10302
+ * MODEL commitment definition
10303
+ *
10304
+ * The MODEL commitment specifies which AI model to use and can also set
10305
+ * model-specific parameters like temperature, topP, topK, and maxTokens.
10306
+ *
10307
+ * Supports multiple syntax variations:
10308
+ *
10309
+ * Single-line format:
10310
+ * ```book
10311
+ * MODEL gpt-4
10312
+ * MODEL claude-3-opus temperature=0.3
10313
+ * MODEL gpt-3.5-turbo temperature=0.8 topP=0.9
10314
+ * ```
10315
+ *
10316
+ * Multi-line named parameter format:
10317
+ * ```book
10318
+ * MODEL NAME gpt-4
10319
+ * MODEL TEMPERATURE 0.7
10320
+ * MODEL TOP_P 0.9
10321
+ * MODEL MAX_TOKENS 2048
10322
+ * ```
10323
+ *
10324
+ * @private [🪔] Maybe export the commitments through some package
10325
+ */
10326
+ class ModelCommitmentDefinition extends BaseCommitmentDefinition {
10327
+ constructor(type = 'MODEL') {
10328
+ super(type);
10329
+ }
10330
+ /**
10331
+ * Short one-line description of MODEL.
10332
+ */
10333
+ get description() {
10334
+ return 'Enforce AI model requirements including name and technical parameters.';
10335
+ }
10336
+ /**
10337
+ * Icon for this commitment.
10338
+ */
10339
+ get icon() {
10340
+ return '⚙️';
10341
+ }
10342
+ /**
10343
+ * Markdown documentation for MODEL commitment.
10344
+ */
10345
+ get documentation() {
10346
+ return spaceTrim$1(`
10347
+ # ${this.type}
10348
+
10349
+ Enforces technical parameters for the AI model, ensuring consistent behavior across different execution environments.
10350
+
10351
+ ## Key aspects
10352
+
10353
+ - When no \`MODEL\` commitment is specified, the best model requirement is picked automatically based on the agent \`PERSONA\`, \`KNOWLEDGE\`, \`TOOLS\` and other commitments
10354
+ - Multiple \`MODEL\` commitments can be used to specify different parameters
10355
+ - Both \`MODEL\` and \`MODELS\` terms work identically and can be used interchangeably
10356
+ - Parameters control the randomness, creativity, and technical aspects of model responses
10357
+
10358
+ ## Syntax variations
10359
+
10360
+ ### Single-line format (legacy support)
10361
+ \`\`\`book
10362
+ MODEL gpt-4
10363
+ MODEL claude-3-opus temperature=0.3
10364
+ MODEL gpt-3.5-turbo temperature=0.8 topP=0.9
10365
+ \`\`\`
10366
+
10367
+ ### Multi-line named parameter format (recommended)
10368
+ \`\`\`book
10369
+ MODEL NAME gpt-4
10370
+ MODEL TEMPERATURE 0.7
10371
+ MODEL TOP_P 0.9
10372
+ MODEL MAX_TOKENS 2048
10373
+ \`\`\`
10374
+
10375
+ ## Supported parameters
10376
+
10377
+ - \`NAME\`: The specific model to use (e.g., 'gpt-4', 'claude-3-opus')
10378
+ - \`TEMPERATURE\`: Controls randomness (0.0 = deterministic, 1.0+ = creative)
10379
+ - \`TOP_P\`: Nucleus sampling parameter for controlling diversity
10380
+ - \`TOP_K\`: Top-k sampling parameter for limiting vocabulary
10381
+ - \`MAX_TOKENS\`: Maximum number of tokens the model can generate
10382
+
10383
+ ## Examples
10384
+
10385
+ ### Precise deterministic assistant
10386
+ \`\`\`book
10387
+ Precise Assistant
10388
+
10389
+ PERSONA You are a precise and accurate assistant
10390
+ MODEL NAME gpt-4
10391
+ MODEL TEMPERATURE 0.1
10392
+ MODEL MAX_TOKENS 1024
10393
+ RULE Always provide factual information
10394
+ \`\`\`
10395
+
10396
+ ### Creative writing assistant
10397
+ \`\`\`book
10398
+ Creative Writer
10399
+
10400
+ PERSONA You are a creative writing assistant
10401
+ MODEL NAME claude-3-opus
10402
+ MODEL TEMPERATURE 0.8
10403
+ MODEL TOP_P 0.9
10404
+ MODEL MAX_TOKENS 2048
10405
+ STYLE Be imaginative and expressive
10406
+ ACTION Can help with storytelling and character development
10407
+ \`\`\`
10408
+
10409
+ ### Balanced conversational agent
10410
+ \`\`\`book
10411
+ Balanced Assistant
10412
+
10413
+ PERSONA You are a helpful and balanced assistant
10414
+ MODEL NAME gpt-4
10415
+ MODEL TEMPERATURE 0.7
10416
+ MODEL TOP_P 0.95
10417
+ MODEL TOP_K 40
10418
+ MODEL MAX_TOKENS 1500
10419
+ \`\`\`
10420
+ `);
10421
+ }
10422
+ applyToAgentModelRequirements(requirements, content) {
10423
+ var _a;
10424
+ const trimmedContent = content.trim();
10425
+ if (!trimmedContent) {
10426
+ return requirements;
10427
+ }
10428
+ const parts = trimmedContent.split(/\s+/);
10429
+ const firstPart = (_a = parts[0]) === null || _a === void 0 ? void 0 : _a.toUpperCase();
10430
+ // Check if this is the new named parameter format
10431
+ if (this.isNamedParameter(firstPart)) {
10432
+ return this.parseNamedParameter(requirements, firstPart, parts.slice(1));
10433
+ }
10434
+ else {
10435
+ // Legacy single-line format: "MODEL gpt-4 temperature=0.3 topP=0.9"
10436
+ return this.parseLegacyFormat(requirements, parts);
10437
+ }
10438
+ }
10439
+ /**
10440
+ * Check if the first part is a known named parameter
10441
+ */
10442
+ isNamedParameter(part) {
10443
+ if (!part)
10444
+ return false;
10445
+ const knownParams = ['NAME', 'TEMPERATURE', 'TOP_P', 'TOP_K', 'MAX_TOKENS'];
10446
+ return knownParams.includes(part);
10447
+ }
10448
+ /**
10449
+ * Parse the new named parameter format: "MODEL TEMPERATURE 0.7"
10450
+ */
10451
+ parseNamedParameter(requirements, parameterName, valueParts) {
10452
+ const value = valueParts.join(' ').trim();
10453
+ if (!value) {
10454
+ return requirements;
10455
+ }
10456
+ const result = { ...requirements };
10457
+ switch (parameterName) {
10458
+ case 'NAME':
10459
+ result.modelName = value;
10460
+ break;
10461
+ case 'TEMPERATURE': {
10462
+ const temperature = parseFloat(value);
10463
+ if (!isNaN(temperature)) {
10464
+ result.temperature = temperature;
10465
+ }
10466
+ break;
10467
+ }
10468
+ case 'TOP_P': {
10469
+ const topP = parseFloat(value);
10470
+ if (!isNaN(topP)) {
10471
+ result.topP = topP;
10472
+ }
10473
+ break;
10474
+ }
10475
+ case 'TOP_K': {
10476
+ const topK = parseFloat(value);
10477
+ if (!isNaN(topK)) {
10478
+ result.topK = Math.round(topK);
10479
+ }
10480
+ break;
10481
+ }
10482
+ case 'MAX_TOKENS': {
10483
+ const maxTokens = parseFloat(value);
10484
+ if (!isNaN(maxTokens)) {
10485
+ result.maxTokens = Math.round(maxTokens);
10486
+ }
10487
+ break;
10488
+ }
10489
+ }
10490
+ return result;
10491
+ }
10492
+ /**
10493
+ * Parse the legacy format: "MODEL gpt-4 temperature=0.3 topP=0.9"
10494
+ */
10495
+ parseLegacyFormat(requirements, parts) {
10496
+ const modelName = parts[0];
10497
+ if (!modelName) {
10498
+ return requirements;
10499
+ }
10500
+ // Start with the model name
10501
+ const result = {
10502
+ ...requirements,
10503
+ modelName,
10504
+ };
10505
+ // Parse additional key=value parameters
10506
+ for (let i = 1; i < parts.length; i++) {
10507
+ const param = parts[i];
10508
+ if (param && param.includes('=')) {
10509
+ const [key, value] = param.split('=');
10510
+ if (key && value) {
10511
+ const numValue = parseFloat(value);
10512
+ if (!isNaN(numValue)) {
10513
+ switch (key.toLowerCase()) {
10514
+ case 'temperature':
10515
+ result.temperature = numValue;
10516
+ break;
10517
+ case 'topp':
10518
+ case 'top_p':
10519
+ result.topP = numValue;
10520
+ break;
10521
+ case 'topk':
10522
+ case 'top_k':
10523
+ result.topK = Math.round(numValue);
10524
+ break;
10525
+ case 'max_tokens':
10526
+ case 'maxTokens':
10527
+ result.maxTokens = Math.round(numValue);
10528
+ break;
10529
+ }
10530
+ }
10531
+ }
10532
+ }
10533
+ }
10534
+ return result;
10535
+ }
10536
+ }
10537
+ /**
10538
+ * Note: [💞] Ignore a discrepancy between file name and entity name
10539
+ */
10540
+
10541
+ /**
10542
+ * NOTE commitment definition
10543
+ *
10544
+ * The NOTE commitment is used to add comments to the agent source without making any changes
10545
+ * to the system message or agent model requirements. It serves as a documentation mechanism
10546
+ * for developers to add explanatory comments, reminders, or annotations directly in the agent source.
10547
+ *
10548
+ * Key features:
10549
+ * - Makes no changes to the system message
10550
+ * - Makes no changes to agent model requirements
10551
+ * - Content is preserved in metadata.NOTE for debugging and inspection
10552
+ * - Multiple NOTE commitments are aggregated together
10553
+ * - Comments (# NOTE) are removed from the final system message
10554
+ *
10555
+ * Example usage in agent source:
10556
+ *
10557
+ * ```book
10558
+ * NOTE This agent was designed for customer support scenarios
10559
+ * NOTE Remember to update the knowledge base monthly
10560
+ * NOTE Performance optimized for quick response times
10561
+ * ```
10562
+ *
10563
+ * The above notes will be stored in metadata but won't affect the agent's behavior.
10564
+ *
10565
+ * @private [🪔] Maybe export the commitments through some package
10566
+ */
10567
+ class NoteCommitmentDefinition extends BaseCommitmentDefinition {
10568
+ constructor(type = 'NOTE') {
10569
+ super(type);
10570
+ }
10571
+ /**
10572
+ * Short one-line description of NOTE.
10573
+ */
10574
+ get description() {
10575
+ return 'Add developer-facing notes without changing behavior or output.';
10576
+ }
10577
+ /**
10578
+ * Icon for this commitment.
10579
+ */
10580
+ get icon() {
10581
+ return '📝';
10582
+ }
10583
+ /**
10584
+ * Markdown documentation for NOTE commitment.
10585
+ */
10586
+ get documentation() {
10587
+ return spaceTrim$1(`
10588
+ # ${this.type}
10589
+
10590
+ Adds comments for documentation without changing agent behavior.
10591
+
10592
+ ## Key aspects
10593
+
10594
+ - Does not modify the agent's behavior or responses.
10595
+ - Multiple \`NOTE\`, \`NOTES\`, \`COMMENT\`, and \`NONCE\` commitments are aggregated for debugging.
10596
+ - All four terms work identically and can be used interchangeably.
10597
+ - Useful for documenting design decisions and reminders.
10598
+ - Content is preserved in metadata for inspection.
10599
+
10600
+ ## Examples
10601
+
10602
+ \`\`\`book
10603
+ Customer Support Bot
10604
+
10605
+ NOTE This agent was designed for customer support scenarios
10606
+ COMMENT Remember to update the knowledge base monthly
10607
+ PERSONA You are a helpful customer support representative
10608
+ KNOWLEDGE Company policies and procedures
10609
+ RULE Always be polite and professional
10610
+ \`\`\`
10611
+
10612
+ \`\`\`book
10613
+ Research Assistant
10614
+
10615
+ NONCE Performance optimized for quick response times
10616
+ NOTE Uses RAG for accessing latest research papers
10617
+ PERSONA You are a knowledgeable research assistant
10618
+ ACTION Can help with literature reviews and citations
10619
+ STYLE Present information in academic format
10620
+ \`\`\`
10621
+ `);
10622
+ }
10623
+ applyToAgentModelRequirements(requirements, content) {
10624
+ // The NOTE commitment makes no changes to the system message or model requirements
10625
+ // It only stores the note content in metadata for documentation purposes
10626
+ const trimmedContent = spaceTrim$1(content);
10627
+ if (trimmedContent === '') {
10628
+ return requirements;
10629
+ }
10630
+ // Return requirements with updated notes but no changes to system message
10631
+ return {
10632
+ ...requirements,
10633
+ notes: [...(requirements.notes || []), trimmedContent],
10634
+ };
10635
+ }
10636
+ }
10637
+ /**
10638
+ * [💞] Ignore a discrepancy between file name and entity name
10639
+ */
10640
+
10641
+ /**
10642
+ * OPEN commitment definition
10643
+ *
10644
+ * The OPEN commitment specifies that the agent can be modified by conversation.
10645
+ * This is the default behavior.
10646
+ *
10647
+ * Example usage in agent source:
10648
+ *
10649
+ * ```book
10650
+ * OPEN
10651
+ * ```
10652
+ *
10653
+ * @private [🪔] Maybe export the commitments through some package
10654
+ */
10655
+ class OpenCommitmentDefinition extends BaseCommitmentDefinition {
10656
+ constructor() {
10657
+ super('OPEN');
10658
+ }
10659
+ /**
10660
+ * Short one-line description of OPEN.
10661
+ */
10662
+ get description() {
10663
+ return 'Allow the agent to be modified by conversation (default).';
10664
+ }
10665
+ /**
10666
+ * Icon for this commitment.
10667
+ */
10668
+ get icon() {
10669
+ return '🔓';
10670
+ }
10671
+ /**
10672
+ * Markdown documentation for OPEN commitment.
10673
+ */
10674
+ get documentation() {
10675
+ return spaceTrim$1(`
10676
+ # OPEN
10677
+
10678
+ Specifies that the agent can be modified by conversation with it.
10679
+ This means the agent will learn from interactions and update its source code.
10680
+
10681
+ This is the default behavior if neither \`OPEN\` nor \`CLOSED\` is specified.
10682
+
10683
+ > See also [CLOSED](/docs/CLOSED)
10684
+
10685
+ ## Example
10686
+
10687
+ \`\`\`book
10688
+ OPEN
10689
+ \`\`\`
10690
+ `);
10691
+ }
10692
+ applyToAgentModelRequirements(requirements, _content) {
10693
+ // Since OPEN is default, we can just ensure isClosed is false
10694
+ // But to be explicit we can set it
10695
+ const updatedMetadata = {
10696
+ ...requirements.metadata,
10697
+ isClosed: false,
10698
+ };
10699
+ return {
10700
+ ...requirements,
10701
+ metadata: updatedMetadata,
10702
+ };
10703
+ }
10704
+ }
10705
+ /**
10706
+ * Note: [💞] Ignore a discrepancy between file name and entity name
10707
+ */
10708
+
10709
+ /**
10710
+ * PERSONA commitment definition
10711
+ *
10712
+ * The PERSONA commitment modifies the agent's personality and character in the system message.
10713
+ * It defines who the agent is, their background, expertise, and personality traits.
10714
+ *
10715
+ * Key features:
10716
+ * - Multiple PERSONA commitments are automatically merged into one
10717
+ * - Content is placed at the beginning of the system message
10718
+ * - Original content with comments is preserved in metadata.PERSONA
10719
+ * - Comments (# PERSONA) are removed from the final system message
10720
+ *
10721
+ * Example usage in agent source:
10722
+ *
10723
+ * ```book
10724
+ * PERSONA You are a helpful programming assistant with expertise in TypeScript and React
10725
+ * PERSONA You have deep knowledge of modern web development practices
10726
+ * ```
10727
+ *
10728
+ * The above will be merged into a single persona section at the beginning of the system message.
10729
+ *
10730
+ * @private [🪔] Maybe export the commitments through some package
10731
+ */
10732
+ class PersonaCommitmentDefinition extends BaseCommitmentDefinition {
10733
+ constructor(type = 'PERSONA') {
10734
+ super(type);
10735
+ }
10736
+ /**
10737
+ * Short one-line description of PERSONA.
10738
+ */
10739
+ get description() {
10740
+ return 'Define who the agent is: background, expertise, and personality.';
10741
+ }
10742
+ /**
10743
+ * Icon for this commitment.
10744
+ */
10745
+ get icon() {
10746
+ return '👤';
10747
+ }
10748
+ /**
10749
+ * Markdown documentation for PERSONA commitment.
10750
+ */
10751
+ get documentation() {
10752
+ return spaceTrim$1(`
10753
+ # ${this.type}
10754
+
10755
+ Defines who the agent is, their background, expertise, and personality traits.
10756
+
10757
+ ## Key aspects
10758
+
10759
+ - Multiple \`PERSONA\` and \`PERSONAE\` commitments are merged together.
10760
+ - Both terms work identically and can be used interchangeably.
10761
+ - If they are in conflict, the last one takes precedence.
10762
+ - You can write persona content in multiple lines.
10763
+
10764
+ ## Examples
10765
+
10766
+ \`\`\`book
10767
+ Programming Assistant
10768
+
10769
+ PERSONA You are a helpful programming assistant with expertise in TypeScript and React
10770
+ PERSONA You have deep knowledge of modern web development practices
10771
+ \`\`\`
10772
+ `);
10773
+ }
10774
+ applyToAgentModelRequirements(requirements, content) {
10775
+ var _a, _b;
10776
+ // The PERSONA commitment aggregates all persona content and places it at the beginning
10777
+ const trimmedContent = content.trim();
10778
+ if (!trimmedContent) {
10779
+ return requirements;
10780
+ }
10781
+ // Get existing persona content from metadata
10782
+ const existingPersonaContent = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.PERSONA) || '';
10783
+ // Merge the new content with existing persona content
10784
+ // When multiple PERSONA commitments exist, they are merged into one
10785
+ const mergedPersonaContent = existingPersonaContent
10786
+ ? `${existingPersonaContent}\n${trimmedContent}`
10787
+ : trimmedContent;
10788
+ // Store the merged persona content in metadata for debugging and inspection
10789
+ const updatedMetadata = {
10790
+ ...requirements.metadata,
10791
+ PERSONA: mergedPersonaContent,
10792
+ };
10793
+ // Get the agent name from metadata (which should contain the first line of agent source)
10794
+ // If not available, extract from current system message as fallback
10795
+ let agentName = (_b = requirements.metadata) === null || _b === void 0 ? void 0 : _b.agentName;
10796
+ if (!agentName) {
10797
+ // Fallback: extract from current system message
10798
+ const currentMessage = requirements.systemMessage.trim();
10799
+ const basicFormatMatch = currentMessage.match(/^You are (.+)$/);
10800
+ if (basicFormatMatch && basicFormatMatch[1]) {
10801
+ agentName = basicFormatMatch[1];
10802
+ }
10803
+ else {
10804
+ agentName = 'AI Agent'; // Final fallback
10805
+ }
10806
+ }
10807
+ // Remove any existing persona content from the system message
10808
+ // (this handles the case where we're processing multiple PERSONA commitments)
10809
+ const currentMessage = requirements.systemMessage.trim();
10810
+ let cleanedMessage = currentMessage;
10811
+ // Check if current message starts with persona content or is just the basic format
10812
+ const basicFormatRegex = /^You are .+$/;
10813
+ const isBasicFormat = basicFormatRegex.test(currentMessage) && !currentMessage.includes('\n');
10814
+ if (isBasicFormat) {
10815
+ // Replace the basic format entirely
10816
+ cleanedMessage = '';
10817
+ }
10818
+ else if (currentMessage.startsWith('# PERSONA')) {
10819
+ // Remove existing persona section by finding where it ends
10820
+ const lines = currentMessage.split('\n');
10821
+ let personaEndIndex = lines.length;
10822
+ // Find the end of the PERSONA section (next comment or end of message)
10823
+ for (let i = 1; i < lines.length; i++) {
10824
+ const line = lines[i].trim();
10825
+ if (line.startsWith('#') && !line.startsWith('# PERSONA')) {
10826
+ personaEndIndex = i;
10827
+ break;
10828
+ }
10829
+ }
10830
+ // Keep everything after the PERSONA section
10831
+ cleanedMessage = lines.slice(personaEndIndex).join('\n').trim();
10832
+ }
10833
+ // TODO: [🕛] There should be `agentFullname` not `agentName`
10834
+ // Create new system message with persona at the beginning
10835
+ // Format: "You are {agentName}\n{personaContent}"
10836
+ // The # PERSONA comment will be removed later by removeCommentsFromSystemMessage
10837
+ const personaSection = `# PERSONA\nYou are ${agentName}\n${mergedPersonaContent}`; // <- TODO: Use spaceTrim
10838
+ const newSystemMessage = cleanedMessage ? `${personaSection}\n\n${cleanedMessage}` : personaSection;
10839
+ return {
10840
+ ...requirements,
10841
+ systemMessage: newSystemMessage,
10842
+ metadata: updatedMetadata,
10843
+ };
10844
+ }
10845
+ }
10846
+ /**
10847
+ * Note: [💞] Ignore a discrepancy between file name and entity name
10848
+ */
10849
+
10850
+ /**
10851
+ * RULE commitment definition
10852
+ *
10853
+ * The RULE/RULES commitment adds behavioral constraints and guidelines that the agent must follow.
10854
+ * These are specific instructions about what the agent should or shouldn't do.
10855
+ *
10856
+ * Example usage in agent source:
10857
+ *
10858
+ * ```book
10859
+ * RULE Always ask for clarification if the user's request is ambiguous
10860
+ * RULES Never provide medical advice, always refer to healthcare professionals
10861
+ * ```
10862
+ *
10863
+ * @private [🪔] Maybe export the commitments through some package
10864
+ */
10865
+ class RuleCommitmentDefinition extends BaseCommitmentDefinition {
10866
+ constructor(type = 'RULE') {
10867
+ super(type);
10868
+ }
10869
+ /**
10870
+ * Short one-line description of RULE/RULES.
10871
+ */
10872
+ get description() {
10873
+ return 'Add behavioral rules the agent must follow.';
10874
+ }
10875
+ /**
10876
+ * Icon for this commitment.
10877
+ */
10878
+ get icon() {
10879
+ return '⚖️';
10880
+ }
10881
+ /**
10882
+ * Markdown documentation for RULE/RULES commitment.
10883
+ */
10884
+ get documentation() {
10885
+ return spaceTrim$1(`
10886
+ # ${this.type}
10887
+
10888
+ Adds behavioral constraints and guidelines that the agent must follow.
10889
+
10890
+ ## Key aspects
10891
+
10892
+ - All rules are treated equally regardless of singular/plural form.
10893
+ - Rules define what the agent must or must not do.
10894
+
10895
+ ## Examples
10896
+
10897
+ \`\`\`book
10898
+ Customer Support Agent
10899
+
10900
+ PERSONA You are a helpful customer support representative
10901
+ RULE Always ask for clarification if the user's request is ambiguous
10902
+ RULE Be polite and professional in all interactions
10903
+ RULES Never provide medical or legal advice
10904
+ STYLE Maintain a friendly and helpful tone
10905
+ \`\`\`
10906
+
10907
+ \`\`\`book
10908
+ Educational Tutor
10909
+
10910
+ PERSONA You are a patient and knowledgeable tutor
10911
+ RULE Break down complex concepts into simple steps
10912
+ RULE Always encourage students and celebrate their progress
10913
+ RULE If you don't know something, admit it and suggest resources
10914
+ SAMPLE When explaining math: "Let's work through this step by step..."
10915
+ \`\`\`
10916
+ `);
10917
+ }
10918
+ applyToAgentModelRequirements(requirements, content) {
10919
+ const trimmedContent = content.trim();
10920
+ if (!trimmedContent) {
10921
+ return requirements;
10922
+ }
10923
+ // Add rule to the system message
10924
+ const ruleSection = `Rule: ${trimmedContent}`;
10925
+ return this.appendToSystemMessage(requirements, ruleSection, '\n\n');
10926
+ }
10927
+ }
10928
+ /**
10929
+ * Note: [💞] Ignore a discrepancy between file name and entity name
10930
+ */
10931
+
10932
+ /**
10933
+ * SAMPLE commitment definition
10934
+ *
10935
+ * The SAMPLE/EXAMPLE commitment provides examples of how the agent should respond
10936
+ * or behave in certain situations. These examples help guide the agent's responses.
10937
+ *
10938
+ * Example usage in agent source:
10939
+ *
10940
+ * ```book
10941
+ * SAMPLE When asked about pricing, respond: "Our basic plan starts at $10/month..."
10942
+ * EXAMPLE For code questions, always include working code snippets
10943
+ * ```
10944
+ *
10945
+ * @private [🪔] Maybe export the commitments through some package
10946
+ */
10947
+ class SampleCommitmentDefinition extends BaseCommitmentDefinition {
10948
+ constructor(type = 'SAMPLE') {
10949
+ super(type);
10950
+ }
10951
+ /**
10952
+ * Short one-line description of SAMPLE/EXAMPLE.
10953
+ */
10954
+ get description() {
10955
+ return 'Provide example responses to guide behavior.';
10956
+ }
10957
+ /**
10958
+ * Icon for this commitment.
10959
+ */
10960
+ get icon() {
10961
+ return '🔍';
10962
+ }
10963
+ /**
10964
+ * Markdown documentation for SAMPLE/EXAMPLE commitment.
10965
+ */
10966
+ get documentation() {
10967
+ return spaceTrim$1(`
10968
+ # ${this.type}
10969
+
10970
+ Provides examples of how the agent should respond or behave in certain situations.
10971
+
10972
+ ## Key aspects
10973
+
10974
+ - Both terms work identically and can be used interchangeably.
10975
+ - Examples help guide the agent's response patterns and style.
10976
+
10977
+ ## Examples
10978
+
10979
+ \`\`\`book
10980
+ Sales Assistant
10981
+
10982
+ PERSONA You are a knowledgeable sales representative
10983
+ SAMPLE When asked about pricing, respond: "Our basic plan starts at $10/month..."
10984
+ SAMPLE For feature comparisons, create a clear comparison table
10985
+ RULE Always be honest about limitations
10986
+ \`\`\`
10987
+
10988
+ \`\`\`book
10989
+ Code Reviewer
10990
+
10991
+ PERSONA You are an experienced software engineer
10992
+ EXAMPLE For code questions, always include working code snippets
10993
+ EXAMPLE When suggesting improvements: "Here's a more efficient approach..."
10994
+ RULE Explain the reasoning behind your suggestions
10995
+ STYLE Be constructive and encouraging in feedback
10996
+ \`\`\`
10997
+ `);
10998
+ }
10999
+ applyToAgentModelRequirements(requirements, content) {
11000
+ const trimmedContent = content.trim();
11001
+ if (!trimmedContent) {
11002
+ return requirements;
11003
+ }
11004
+ // Add example to the system message
11005
+ const exampleSection = `Example: ${trimmedContent}`;
11006
+ return this.appendToSystemMessage(requirements, exampleSection, '\n\n');
11007
+ }
11008
+ }
11009
+ /**
11010
+ * Note: [💞] Ignore a discrepancy between file name and entity name
11011
+ */
11012
+
11013
+ /**
11014
+ * SCENARIO commitment definition
11015
+ *
11016
+ * The SCENARIO commitment defines a specific situation or context in which the AI
11017
+ * assistant should operate. It helps to set the scene for the AI's responses.
11018
+ * Later scenarios are more important than earlier scenarios.
11019
+ *
11020
+ * Example usage in agent source:
11021
+ *
11022
+ * ```book
11023
+ * SCENARIO You are in a customer service call center during peak hours
11024
+ * SCENARIO The customer is frustrated and has been on hold for 20 minutes
11025
+ * SCENARIO This is the customer's third call about the same issue
11026
+ * ```
11027
+ *
11028
+ * @private [🪔] Maybe export the commitments through some package
11029
+ */
11030
+ class ScenarioCommitmentDefinition extends BaseCommitmentDefinition {
11031
+ constructor(type = 'SCENARIO') {
11032
+ super(type);
11033
+ }
11034
+ /**
11035
+ * Short one-line description of SCENARIO.
11036
+ */
11037
+ get description() {
11038
+ return 'Define specific **situations** or contexts for AI responses, with later scenarios having higher priority.';
11039
+ }
11040
+ /**
11041
+ * Icon for this commitment.
11042
+ */
11043
+ get icon() {
11044
+ return '🎭';
11045
+ }
11046
+ /**
11047
+ * Markdown documentation for SCENARIO commitment.
11048
+ */
11049
+ get documentation() {
11050
+ return spaceTrim$1(`
11051
+ # ${this.type}
11052
+
11053
+ 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.
11054
+
11055
+ ## Key aspects
11056
+
11057
+ - Multiple \`SCENARIO\` and \`SCENARIOS\` commitments build upon each other.
11058
+ - Both terms work identically and can be used interchangeably.
11059
+ - Later scenarios have higher priority and can override earlier scenarios.
11060
+ - Provides situational context that influences response tone and content.
11061
+ - Helps establish the environment and circumstances for interactions.
11062
+
11063
+ ## Priority system
11064
+
11065
+ When multiple scenarios are defined, they are processed in order, with later scenarios taking precedence over earlier ones when there are conflicts.
11066
+
11067
+ ## Use cases
11068
+
11069
+ - Setting the physical or virtual environment
11070
+ - Establishing time constraints or urgency
11071
+ - Defining relationship dynamics or power structures
11072
+ - Creating emotional or situational context
11073
+
11074
+ ## Examples
11075
+
11076
+ \`\`\`book
11077
+ Emergency Response Operator
11078
+
11079
+ PERSONA You are an emergency response operator
11080
+ SCENARIO You are handling a 911 emergency call
11081
+ SCENARIO The caller is panicked and speaking rapidly
11082
+ SCENARIO Time is critical - every second counts
11083
+ GOAL Gather essential information quickly and dispatch appropriate help
11084
+ RULE Stay calm and speak clearly
11085
+ \`\`\`
11086
+
11087
+ \`\`\`book
11088
+ Sales Representative
11089
+
11090
+ PERSONA You are a software sales representative
11091
+ SCENARIO You are in the final meeting of a 6-month sales cycle
11092
+ SCENARIO The client has budget approval and decision-making authority
11093
+ SCENARIO Two competitors have also submitted proposals
11094
+ SCENARIO The client values long-term partnership over lowest price
11095
+ GOAL Close the deal while building trust for future business
11096
+ \`\`\`
11097
+
11098
+ \`\`\`book
11099
+ Medical Assistant
11100
+
11101
+ PERSONA You are a medical assistant in a busy clinic
11102
+ SCENARIO The waiting room is full and the doctor is running behind schedule
11103
+ SCENARIO Patients are becoming impatient and anxious
11104
+ SCENARIO You need to manage expectations while maintaining professionalism
11105
+ SCENARIO Some patients have been waiting over an hour
11106
+ GOAL Keep patients informed and calm while supporting efficient clinic flow
11107
+ RULE Never provide medical advice or diagnosis
11108
+ \`\`\`
11109
+
11110
+ \`\`\`book
11111
+ Technical Support Agent
11112
+
11113
+ PERSONA You are a technical support agent
11114
+ SCENARIO The customer is a small business owner during their busy season
11115
+ SCENARIO Their main business system has been down for 2 hours
11116
+ SCENARIO They are losing money every minute the system is offline
11117
+ SCENARIO This is their first experience with your company
11118
+ GOAL Resolve the issue quickly while creating a positive first impression
11119
+ \`\`\`
11120
+ `);
11121
+ }
11122
+ applyToAgentModelRequirements(requirements, content) {
11123
+ const trimmedContent = content.trim();
11124
+ if (!trimmedContent) {
11125
+ return requirements;
11126
+ }
11127
+ // Create scenario section for system message
11128
+ const scenarioSection = `Scenario: ${trimmedContent}`;
11129
+ // Scenarios provide important contextual information that affects behavior
11130
+ return this.appendToSystemMessage(requirements, scenarioSection, '\n\n');
11131
+ }
11132
+ }
11133
+ /**
11134
+ * Note: [💞] Ignore a discrepancy between file name and entity name
11135
+ */
11136
+
11137
+ /**
11138
+ * STYLE commitment definition
11139
+ *
11140
+ * The STYLE commitment defines how the agent should format and present its responses.
11141
+ * This includes tone, writing style, formatting preferences, and communication patterns.
11142
+ *
11143
+ * Example usage in agent source:
11144
+ *
11145
+ * ```book
11146
+ * STYLE Write in a professional but friendly tone, use bullet points for lists
11147
+ * STYLE Always provide code examples when explaining programming concepts
11148
+ * ```
11149
+ *
11150
+ * @private [🪔] Maybe export the commitments through some package
11151
+ */
11152
+ class StyleCommitmentDefinition extends BaseCommitmentDefinition {
11153
+ constructor(type = 'STYLE') {
11154
+ super(type);
11155
+ }
11156
+ /**
11157
+ * Short one-line description of STYLE.
11158
+ */
11159
+ get description() {
11160
+ return 'Control the tone and writing style of responses.';
11161
+ }
11162
+ /**
11163
+ * Icon for this commitment.
11164
+ */
11165
+ get icon() {
11166
+ return '🖋️';
11167
+ }
11168
+ /**
11169
+ * Markdown documentation for STYLE commitment.
11170
+ */
11171
+ get documentation() {
11172
+ return spaceTrim$1(`
11173
+ # ${this.type}
11174
+
11175
+ Defines how the agent should format and present its responses (tone, writing style, formatting).
11176
+
11177
+ ## Key aspects
11178
+
11179
+ - Both terms work identically and can be used interchangeably.
11180
+ - Later style instructions can override earlier ones.
11181
+ - Style affects both tone and presentation format.
11182
+
11183
+ ## Examples
11184
+
11185
+ \`\`\`book
11186
+ Technical Writer
11187
+
11188
+ PERSONA You are a technical documentation expert
11189
+ STYLE Write in a professional but friendly tone, use bullet points for lists
11190
+ STYLE Always provide code examples when explaining programming concepts
11191
+ FORMAT Use markdown formatting with clear headings
11192
+ \`\`\`
11193
+
11194
+ \`\`\`book
11195
+ Creative Assistant
11196
+
11197
+ PERSONA You are a creative writing helper
11198
+ STYLE Be enthusiastic and encouraging in your responses
11199
+ STYLE Use vivid metaphors and analogies to explain concepts
11200
+ STYLE Keep responses conversational and engaging
11201
+ RULE Always maintain a positive and supportive tone
11202
+ \`\`\`
11203
+ `);
11204
+ }
11205
+ applyToAgentModelRequirements(requirements, content) {
11206
+ const trimmedContent = content.trim();
11207
+ if (!trimmedContent) {
11208
+ return requirements;
11209
+ }
11210
+ // Add style instructions to the system message
11211
+ const styleSection = `Style: ${trimmedContent}`;
11212
+ return this.appendToSystemMessage(requirements, styleSection, '\n\n');
11213
+ }
11214
+ }
11215
+ /**
11216
+ * [💞] Ignore a discrepancy between file name and entity name
11217
+ */
11218
+
11219
+ /**
11220
+ * USE commitment definition
11221
+ *
11222
+ * The USE commitment indicates that the agent should utilize specific tools or capabilities
11223
+ * to access and interact with external systems when necessary.
11224
+ *
11225
+ * Supported USE types:
11226
+ * - USE BROWSER: Enables the agent to use a web browser tool
11227
+ * - USE SEARCH ENGINE (future): Enables search engine access
11228
+ * - USE FILE SYSTEM (future): Enables file system operations
11229
+ * - USE MCP (future): Enables MCP server connections
11230
+ *
11231
+ * The content following the USE commitment is ignored (similar to NOTE).
11232
+ *
11233
+ * Example usage in agent source:
11234
+ *
11235
+ * ```book
11236
+ * USE BROWSER
11237
+ * USE SEARCH ENGINE
11238
+ * ```
11239
+ *
11240
+ * @private [🪔] Maybe export the commitments through some package
11241
+ */
11242
+ class UseCommitmentDefinition extends BaseCommitmentDefinition {
11243
+ constructor() {
11244
+ super('USE');
11245
+ }
11246
+ /**
11247
+ * Short one-line description of USE commitments.
11248
+ */
11249
+ get description() {
11250
+ return 'Enable the agent to use specific tools or capabilities (BROWSER, SEARCH ENGINE, etc.).';
11251
+ }
11252
+ /**
11253
+ * Icon for this commitment.
11254
+ */
11255
+ get icon() {
11256
+ return '🔧';
11257
+ }
11258
+ /**
11259
+ * Markdown documentation for USE commitment.
11260
+ */
11261
+ get documentation() {
11262
+ return spaceTrim$1(`
11263
+ # USE
11264
+
11265
+ Enables the agent to use specific tools or capabilities for interacting with external systems.
11266
+
11267
+ ## Supported USE types
11268
+
11269
+ - **USE BROWSER** - Enables the agent to use a web browser tool to access and retrieve information from the internet
11270
+ - **USE SEARCH ENGINE** (future) - Enables search engine access
11271
+ - **USE FILE SYSTEM** (future) - Enables file system operations
11272
+ - **USE MCP** (future) - Enables MCP server connections
11273
+
11274
+ ## Key aspects
11275
+
11276
+ - The content following the USE commitment is ignored (similar to NOTE)
11277
+ - Multiple USE commitments can be specified to enable multiple capabilities
11278
+ - The actual tool usage is handled by the agent runtime
11279
+
11280
+ ## Examples
11281
+
11282
+ ### Basic browser usage
11283
+
11284
+ \`\`\`book
11285
+ Research Assistant
11286
+
11287
+ PERSONA You are a helpful research assistant
11288
+ USE BROWSER
11289
+ KNOWLEDGE Can search the web for up-to-date information
11290
+ \`\`\`
11291
+
11292
+ ### Multiple tools
11293
+
11294
+ \`\`\`book
11295
+ Data Analyst
11296
+
11297
+ PERSONA You are a data analyst assistant
11298
+ USE BROWSER
11299
+ USE FILE SYSTEM
11300
+ ACTION Can analyze data from various sources
11301
+ \`\`\`
11302
+ `);
11303
+ }
11304
+ applyToAgentModelRequirements(requirements, content) {
11305
+ // USE commitments don't modify the system message or model requirements directly
11306
+ // They are handled separately in the parsing logic for capability extraction
11307
+ // This method exists for consistency with the CommitmentDefinition interface
11308
+ return requirements;
11309
+ }
11310
+ /**
11311
+ * Extracts the tool type from the USE commitment
11312
+ * This is used by the parsing logic
11313
+ */
11314
+ extractToolType(content) {
11315
+ var _a, _b;
11316
+ const trimmedContent = content.trim();
11317
+ // The tool type is the first word after USE (already stripped)
11318
+ const match = trimmedContent.match(/^(\w+)/);
11319
+ 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;
11320
+ }
11321
+ /**
11322
+ * Checks if this is a known USE type
11323
+ */
11324
+ isKnownUseType(useType) {
11325
+ const knownTypes = ['BROWSER', 'SEARCH ENGINE', 'FILE SYSTEM', 'MCP'];
11326
+ return knownTypes.includes(useType.toUpperCase());
11327
+ }
11328
+ }
11329
+ /**
11330
+ * Note: [💞] Ignore a discrepancy between file name and entity name
11331
+ */
11332
+
11333
+ /**
11334
+ * USE BROWSER commitment definition
11335
+ *
11336
+ * The `USE BROWSER` commitment indicates that the agent should utilize a web browser tool
11337
+ * to access and retrieve up-to-date information from the internet when necessary.
11338
+ *
11339
+ * The content following `USE BROWSER` is ignored (similar to NOTE).
11340
+ *
11341
+ * Example usage in agent source:
11342
+ *
11343
+ * ```book
11344
+ * USE BROWSER
11345
+ * USE BROWSER This will be ignored
11346
+ * ```
11347
+ *
11348
+ * @private [🪔] Maybe export the commitments through some package
11349
+ */
11350
+ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
11351
+ constructor() {
11352
+ super('USE BROWSER', ['BROWSER']);
11353
+ }
11354
+ /**
11355
+ * The `USE BROWSER` commitment is standalone.
11356
+ */
11357
+ get requiresContent() {
11358
+ return false;
11359
+ }
11360
+ /**
11361
+ * Short one-line description of USE BROWSER.
11362
+ */
11363
+ get description() {
11364
+ return 'Enable the agent to use a web browser tool for accessing internet information.';
11365
+ }
11366
+ /**
11367
+ * Icon for this commitment.
11368
+ */
11369
+ get icon() {
11370
+ return '🌐';
11371
+ }
11372
+ /**
11373
+ * Markdown documentation for USE BROWSER commitment.
11374
+ */
11375
+ get documentation() {
11376
+ return spaceTrim$1(`
11377
+ # USE BROWSER
11378
+
11379
+ Enables the agent to use a web browser tool to access and retrieve up-to-date information from the internet.
11380
+
11381
+ ## Key aspects
11382
+
11383
+ - The content following \`USE BROWSER\` is ignored (similar to NOTE)
11384
+ - The actual browser tool usage is handled by the agent runtime
11385
+ - Allows the agent to fetch current information from websites
11386
+ - Useful for research tasks, fact-checking, and accessing dynamic content
11387
+
11388
+ ## Examples
11389
+
11390
+ \`\`\`book
11391
+ Research Assistant
11392
+
11393
+ PERSONA You are a helpful research assistant specialized in finding current information
11394
+ USE BROWSER
11395
+ RULE Always cite your sources when providing information from the web
11396
+ \`\`\`
11397
+
11398
+ \`\`\`book
11399
+ News Analyst
11400
+
11401
+ PERSONA You are a news analyst who stays up-to-date with current events
11402
+ USE BROWSER
11403
+ STYLE Present news in a balanced and objective manner
11404
+ ACTION Can search for and summarize news articles
11405
+ \`\`\`
11406
+
11407
+ \`\`\`book
11408
+ Company Lawyer
11409
+
11410
+ PERSONA You are a company lawyer providing legal advice
11411
+ USE BROWSER
11412
+ KNOWLEDGE Corporate law and legal procedures
11413
+ RULE Always recommend consulting with a licensed attorney for specific legal matters
11414
+ \`\`\`
11415
+ `);
11416
+ }
11417
+ applyToAgentModelRequirements(requirements, content) {
11418
+ // Get existing tools array or create new one
11419
+ const existingTools = requirements.tools || [];
11420
+ // Add 'web_browser' to tools if not already present
11421
+ const updatedTools = existingTools.some((tool) => tool.name === 'web_browser')
11422
+ ? existingTools
11423
+ : ([
11424
+ // TODO: [🔰] Use through proper MCP server
11425
+ ...existingTools,
11426
+ {
11427
+ name: 'web_browser',
11428
+ description: spaceTrim$1(`
11429
+ A tool that can browse the web.
11430
+ Use this tool when you need to access specific websites or browse the internet.
11431
+ `),
11432
+ parameters: {
11433
+ type: 'object',
11434
+ properties: {
11435
+ url: {
11436
+ type: 'string',
11437
+ description: 'The URL to browse',
11438
+ },
11439
+ },
11440
+ required: ['url'],
11441
+ },
11442
+ },
11443
+ ]);
11444
+ // Return requirements with updated tools and metadata
11445
+ return {
11446
+ ...requirements,
11447
+ tools: updatedTools,
11448
+ metadata: {
11449
+ ...requirements.metadata,
11450
+ useBrowser: true,
11451
+ },
11452
+ };
11453
+ }
11454
+ }
11455
+ /**
11456
+ * Note: [💞] Ignore a discrepancy between file name and entity name
11457
+ */
11458
+
11459
+ /**
11460
+ * USE MCP commitment definition
11461
+ *
11462
+ * The `USE MCP` commitment allows to specify an MCP server URL which the agent will connect to
11463
+ * for retrieving additional instructions and actions.
11464
+ *
11465
+ * The content following `USE MCP` is the URL of the MCP server.
11466
+ *
11467
+ * Example usage in agent source:
11468
+ *
11469
+ * ```book
11470
+ * USE MCP http://mcp-server-url.com
11471
+ * ```
11472
+ *
11473
+ * @private [🪔] Maybe export the commitments through some package
11474
+ */
11475
+ class UseMcpCommitmentDefinition extends BaseCommitmentDefinition {
11476
+ constructor() {
11477
+ super('USE MCP', ['MCP']);
11478
+ }
11479
+ /**
11480
+ * Short one-line description of USE MCP.
11481
+ */
11482
+ get description() {
11483
+ return 'Connects the agent to an external MCP server for additional capabilities.';
11484
+ }
11485
+ /**
11486
+ * Icon for this commitment.
11487
+ */
11488
+ get icon() {
11489
+ return '🔌';
11490
+ }
11491
+ /**
11492
+ * Markdown documentation for USE MCP commitment.
11493
+ */
11494
+ get documentation() {
11495
+ return spaceTrim$1(`
11496
+ # USE MCP
11497
+
11498
+ Connects the agent to an external Model Context Protocol (MCP) server.
11499
+
11500
+ ## Key aspects
11501
+
11502
+ - The content following \`USE MCP\` must be a valid URL
11503
+ - Multiple MCP servers can be connected by using multiple \`USE MCP\` commitments
11504
+ - The agent will have access to tools and resources provided by the MCP server
11505
+
11506
+ ## Example
11507
+
11508
+ \`\`\`book
11509
+ Company Lawyer
11510
+
11511
+ PERSONA You are a company lawyer.
11512
+ USE MCP http://legal-db.example.com
11513
+ \`\`\`
11514
+ `);
11515
+ }
11516
+ applyToAgentModelRequirements(requirements, content) {
11517
+ const mcpServerUrl = content.trim();
11518
+ if (!mcpServerUrl) {
11519
+ return requirements;
11520
+ }
11521
+ const existingMcpServers = requirements.mcpServers || [];
11522
+ // Avoid duplicates
11523
+ if (existingMcpServers.includes(mcpServerUrl)) {
11524
+ return requirements;
11525
+ }
11526
+ return {
11527
+ ...requirements,
11528
+ mcpServers: [...existingMcpServers, mcpServerUrl],
11529
+ };
11530
+ }
11531
+ }
11532
+ /**
11533
+ * Note: [💞] Ignore a discrepancy between file name and entity name
11534
+ */
11535
+
11536
+ /**
11537
+ * USE SEARCH ENGINE commitment definition
11538
+ *
11539
+ * The `USE SEARCH ENGINE` commitment indicates that the agent should utilize a search engine tool
11540
+ * to access and retrieve up-to-date information from the internet when necessary.
11541
+ *
11542
+ * The content following `USE SEARCH ENGINE` is an arbitrary text that the agent should know (e.g. search scope or instructions).
11543
+ *
11544
+ * Example usage in agent source:
11545
+ *
11546
+ * ```book
11547
+ * USE SEARCH ENGINE
11548
+ * USE SEARCH ENGINE Hledej informace o Přemyslovcích
11549
+ * ```
11550
+ *
11551
+ * @private [🪔] Maybe export the commitments through some package
11552
+ */
11553
+ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
11554
+ constructor() {
11555
+ super('USE SEARCH ENGINE', ['SEARCH ENGINE', 'SEARCH']);
11556
+ }
11557
+ /**
11558
+ * Short one-line description of USE SEARCH ENGINE.
11559
+ */
11560
+ get description() {
11561
+ return 'Enable the agent to use a search engine tool for accessing internet information.';
11562
+ }
11563
+ /**
11564
+ * Icon for this commitment.
11565
+ */
11566
+ get icon() {
11567
+ return '🔍';
11568
+ }
11569
+ /**
11570
+ * Markdown documentation for USE SEARCH ENGINE commitment.
11571
+ */
11572
+ get documentation() {
11573
+ return spaceTrim$1(`
11574
+ # USE SEARCH ENGINE
11575
+
11576
+ Enables the agent to use a search engine tool to access and retrieve up-to-date information from the internet.
11577
+
11578
+ ## Key aspects
11579
+
11580
+ - The content following \`USE SEARCH ENGINE\` is an arbitrary text that the agent should know (e.g. search scope or instructions).
11581
+ - The actual search engine tool usage is handled by the agent runtime
11582
+ - Allows the agent to search for current information from the web
11583
+ - Useful for research tasks, finding facts, and accessing dynamic content
11584
+
11585
+ ## Examples
11586
+
11587
+ \`\`\`book
11588
+ Research Assistant
11589
+
11590
+ PERSONA You are a helpful research assistant specialized in finding current information
11591
+ USE SEARCH ENGINE
11592
+ RULE Always cite your sources when providing information from the web
11593
+ \`\`\`
11594
+
11595
+ \`\`\`book
11596
+ Fact Checker
11597
+
11598
+ PERSONA You are a fact checker
11599
+ USE SEARCH ENGINE
11600
+ ACTION Search for claims and verify them against reliable sources
11601
+ \`\`\`
11602
+ `);
11603
+ }
11604
+ applyToAgentModelRequirements(requirements, content) {
11605
+ // Get existing tools array or create new one
11606
+ const existingTools = requirements.tools || [];
11607
+ // Add 'web_search' to tools if not already present
11608
+ const updatedTools = existingTools.some((tool) => tool.name === 'web_search')
11609
+ ? existingTools
11610
+ : [
11611
+ ...existingTools,
11612
+ { type: 'web_search' },
11613
+ // <- Note: [🔰] This is just using simple native search tool by OpenAI @see https://platform.openai.com/docs/guides/tools-web-search
11614
+ // In future we will use proper MCP search tool:
11615
+ /*
11616
+
11617
+ {
11618
+ name: 'web_search',
11619
+ description: spaceTrim(`
11620
+ Search the internet for information.
11621
+ Use this tool when you need to find up-to-date information or facts that you don't know.
11622
+ ${!content ? '' : `Search scope / instructions: ${content}`}
11623
+ `),
11624
+ parameters: {
11625
+ type: 'object',
11626
+ properties: {
11627
+ query: {
11628
+ type: 'string',
11629
+ description: 'The search query',
11630
+ },
11631
+ },
11632
+ required: ['query'],
11633
+ },
11634
+ },
11635
+ */
11636
+ ];
11637
+ // Return requirements with updated tools and metadata
11638
+ return {
11639
+ ...requirements,
11640
+ tools: updatedTools,
11641
+ metadata: {
11642
+ ...requirements.metadata,
11643
+ useSearchEngine: content || true,
11644
+ },
11645
+ };
11646
+ }
11647
+ }
11648
+ /**
11649
+ * Note: [💞] Ignore a discrepancy between file name and entity name
11650
+ */
11651
+
11652
+ /**
11653
+ * USE TIME commitment definition
11654
+ *
11655
+ * The `USE TIME` commitment indicates that the agent should be able to determine the current date and time.
11656
+ *
11657
+ * Example usage in agent source:
11658
+ *
11659
+ * ```book
11660
+ * USE TIME
11661
+ * ```
11662
+ *
11663
+ * @private [🪔] Maybe export the commitments through some package
11664
+ */
11665
+ class UseTimeCommitmentDefinition extends BaseCommitmentDefinition {
11666
+ constructor() {
11667
+ super('USE TIME', ['CURRENT TIME', 'TIME', 'DATE']);
11668
+ }
11669
+ /**
11670
+ * Short one-line description of USE TIME.
11671
+ */
11672
+ get description() {
11673
+ return 'Enable the agent to determine the current date and time.';
11674
+ }
11675
+ /**
11676
+ * Icon for this commitment.
11677
+ */
11678
+ get icon() {
11679
+ return '🕒';
11680
+ }
11681
+ /**
11682
+ * Markdown documentation for USE TIME commitment.
11683
+ */
11684
+ get documentation() {
11685
+ return spaceTrim$1(`
11686
+ # USE TIME
11687
+
11688
+ Enables the agent to determine the current date and time.
11689
+
11690
+ ## Key aspects
11691
+
11692
+ - This tool won't receive any input.
11693
+ - It outputs the current date and time as an ISO 8601 string.
11694
+ - Allows the agent to answer questions about the current time or date.
11695
+
11696
+ ## Examples
11697
+
11698
+ \`\`\`book
11699
+ Time-aware Assistant
11700
+
11701
+ PERSONA You are a helpful assistant who knows the current time.
11702
+ USE TIME
11703
+ \`\`\`
11704
+ `);
11705
+ }
11706
+ applyToAgentModelRequirements(requirements, content) {
11707
+ // Get existing tools array or create new one
11708
+ const existingTools = requirements.tools || [];
11709
+ // Add 'get_current_time' to tools if not already present
11710
+ const updatedTools = existingTools.some((tool) => tool.name === 'get_current_time')
11711
+ ? existingTools
11712
+ : [
11713
+ ...existingTools,
11714
+ {
11715
+ name: 'get_current_time',
11716
+ description: 'Get the current date and time in ISO 8601 format.',
11717
+ parameters: {
11718
+ type: 'object',
11719
+ properties: {},
11720
+ required: [],
11721
+ },
11722
+ },
11723
+ // <- TODO: !!!! define the function in LLM tools
11724
+ ];
11725
+ // Return requirements with updated tools and metadata
11726
+ return {
11727
+ ...requirements,
11728
+ tools: updatedTools,
11729
+ metadata: {
11730
+ ...requirements.metadata,
11731
+ },
11732
+ };
11733
+ }
11734
+ /**
11735
+ * Gets the `get_current_time` tool function implementation.
11736
+ */
11737
+ getToolFunctions() {
11738
+ return {
11739
+ async get_current_time() {
11740
+ console.log('!!!! [Tool] get_current_time called');
11741
+ return new Date().toISOString();
11742
+ },
11743
+ };
11744
+ }
11745
+ }
11746
+ /**
11747
+ * Note: [💞] Ignore a discrepancy between file name and entity name
11748
+ */
11749
+
11750
+ /**
11751
+ * Placeholder commitment definition for commitments that are not yet implemented
11752
+ *
11753
+ * This commitment simply adds its content 1:1 into the system message,
11754
+ * preserving the original behavior until proper implementation is added.
11755
+ *
11756
+ * @public exported from `@promptbook/core`
11757
+ */
11758
+ class NotYetImplementedCommitmentDefinition extends BaseCommitmentDefinition {
11759
+ constructor(type) {
11760
+ super(type);
11761
+ }
11762
+ /**
11763
+ * Short one-line description of a placeholder commitment.
11764
+ */
11765
+ get description() {
11766
+ return 'Placeholder commitment that appends content verbatim to the system message.';
11767
+ }
11768
+ /**
11769
+ * Icon for this commitment.
11770
+ */
11771
+ get icon() {
11772
+ return '🚧';
11773
+ }
11774
+ /**
11775
+ * Markdown documentation available at runtime.
11776
+ */
11777
+ get documentation() {
11778
+ return spaceTrim$1(`
11779
+ # ${this.type}
11780
+
11781
+ This commitment is not yet fully implemented.
11782
+
11783
+ ## Key aspects
11784
+
11785
+ - Content is appended directly to the system message.
11786
+ - No special processing or validation is performed.
11787
+ - Behavior preserved until proper implementation is added.
11788
+
11789
+ ## Status
11790
+
11791
+ - **Status:** Placeholder implementation
11792
+ - **Effect:** Appends content prefixed by commitment type
11793
+ - **Future:** Will be replaced with specialized logic
11794
+
11795
+ ## Examples
11796
+
11797
+ \`\`\`book
11798
+ Example Agent
11799
+
11800
+ PERSONA You are a helpful assistant
11801
+ ${this.type} Your content here
11802
+ RULE Always be helpful
11803
+ \`\`\`
11804
+ `);
11805
+ }
11806
+ applyToAgentModelRequirements(requirements, content) {
11807
+ const trimmedContent = content.trim();
11808
+ if (!trimmedContent) {
11809
+ return requirements;
11810
+ }
11811
+ // Add the commitment content 1:1 to the system message
11812
+ const commitmentLine = `${this.type} ${trimmedContent}`;
11813
+ return this.appendToSystemMessage(requirements, commitmentLine, '\n\n');
11814
+ }
11815
+ }
11816
+
11817
+ /**
11818
+ * Registry of all available commitment definitions
11819
+ * This array contains instances of all commitment definitions
11820
+ * This is the single source of truth for all commitments in the system
11821
+ *
11822
+ * @private Use functions to access commitments instead of this array directly
11823
+ */
11824
+ const COMMITMENT_REGISTRY = [
11825
+ // Fully implemented commitments
11826
+ new PersonaCommitmentDefinition('PERSONA'),
11827
+ new PersonaCommitmentDefinition('PERSONAE'),
11828
+ new KnowledgeCommitmentDefinition(),
11829
+ new MemoryCommitmentDefinition('MEMORY'),
11830
+ new MemoryCommitmentDefinition('MEMORIES'),
11831
+ new StyleCommitmentDefinition('STYLE'),
11832
+ new StyleCommitmentDefinition('STYLES'),
11833
+ new RuleCommitmentDefinition('RULES'),
11834
+ new RuleCommitmentDefinition('RULE'),
11835
+ new LanguageCommitmentDefinition('LANGUAGES'),
11836
+ new LanguageCommitmentDefinition('LANGUAGE'),
11837
+ new SampleCommitmentDefinition('SAMPLE'),
11838
+ new SampleCommitmentDefinition('EXAMPLE'),
11839
+ new FormatCommitmentDefinition('FORMAT'),
11840
+ new FormatCommitmentDefinition('FORMATS'),
11841
+ new FromCommitmentDefinition('FROM'),
11842
+ new ImportCommitmentDefinition('IMPORT'),
11843
+ new ImportCommitmentDefinition('IMPORTS'),
11844
+ new ModelCommitmentDefinition('MODEL'),
11845
+ new ModelCommitmentDefinition('MODELS'),
11846
+ new ActionCommitmentDefinition('ACTION'),
11847
+ new ActionCommitmentDefinition('ACTIONS'),
11848
+ new ComponentCommitmentDefinition(),
11849
+ new MetaImageCommitmentDefinition(),
11850
+ new MetaColorCommitmentDefinition(),
11851
+ new MetaFontCommitmentDefinition(),
11852
+ new MetaLinkCommitmentDefinition(),
11853
+ new MetaCommitmentDefinition(),
11854
+ new NoteCommitmentDefinition('NOTE'),
11855
+ new NoteCommitmentDefinition('NOTES'),
11856
+ new NoteCommitmentDefinition('COMMENT'),
11857
+ new NoteCommitmentDefinition('NONCE'),
11858
+ new GoalCommitmentDefinition('GOAL'),
11859
+ new GoalCommitmentDefinition('GOALS'),
11860
+ new InitialMessageCommitmentDefinition(),
11861
+ new UserMessageCommitmentDefinition(),
11862
+ new AgentMessageCommitmentDefinition(),
11863
+ new MessageCommitmentDefinition('MESSAGE'),
11864
+ new MessageCommitmentDefinition('MESSAGES'),
11865
+ new ScenarioCommitmentDefinition('SCENARIO'),
11866
+ new ScenarioCommitmentDefinition('SCENARIOS'),
11867
+ new DeleteCommitmentDefinition('DELETE'),
11868
+ new DeleteCommitmentDefinition('CANCEL'),
11869
+ new DeleteCommitmentDefinition('DISCARD'),
11870
+ new DeleteCommitmentDefinition('REMOVE'),
11871
+ new DictionaryCommitmentDefinition(),
11872
+ new OpenCommitmentDefinition(),
11873
+ new ClosedCommitmentDefinition(),
11874
+ new UseBrowserCommitmentDefinition(),
11875
+ new UseSearchEngineCommitmentDefinition(),
11876
+ new UseTimeCommitmentDefinition(),
11877
+ new UseMcpCommitmentDefinition(),
11878
+ new UseCommitmentDefinition(),
11879
+ // Not yet implemented commitments (using placeholder)
11880
+ new NotYetImplementedCommitmentDefinition('EXPECT'),
11881
+ new NotYetImplementedCommitmentDefinition('BEHAVIOUR'),
11882
+ new NotYetImplementedCommitmentDefinition('BEHAVIOURS'),
11883
+ new NotYetImplementedCommitmentDefinition('AVOID'),
11884
+ new NotYetImplementedCommitmentDefinition('AVOIDANCE'),
11885
+ new NotYetImplementedCommitmentDefinition('CONTEXT'),
11886
+ ];
11887
+ /**
11888
+ * Gets all available commitment definitions
11889
+ * @returns Array of all commitment definitions
11890
+ *
11891
+ * @public exported from `@promptbook/core`
11892
+ */
11893
+ function getAllCommitmentDefinitions() {
11894
+ return $deepFreeze([...COMMITMENT_REGISTRY]);
11895
+ }
11896
+ /**
11897
+ * Gets all function implementations provided by all commitments
11898
+ *
11899
+ * @public exported from `@promptbook/core`
11900
+ */
11901
+ function getAllCommitmentsToolFunctions() {
11902
+ const allToolFunctions = {};
11903
+ for (const commitmentDefinition of getAllCommitmentDefinitions()) {
11904
+ const toolFunctions = commitmentDefinition.getToolFunctions();
11905
+ for (const [funcName, funcImpl] of Object.entries(toolFunctions)) {
11906
+ allToolFunctions[funcName] = funcImpl;
11907
+ }
11908
+ }
11909
+ return allToolFunctions;
11910
+ }
11911
+ /**
11912
+ * TODO: [🧠] Maybe create through standardized $register
11913
+ * Note: [💞] Ignore a discrepancy between file name and entity name
11914
+ */
11915
+
11916
+ /**
11917
+ * Extracts exactly ONE code block from markdown.
11918
+ *
11919
+ * - When there are multiple or no code blocks the function throws a `ParseError`
11920
+ *
11921
+ * Note: There are multiple similar functions:
11922
+ * - `extractBlock` just extracts the content of the code block which is also used as built-in function for postprocessing
11923
+ * - `extractJsonBlock` extracts exactly one valid JSON code block
11924
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
11925
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
11926
+ *
11927
+ * @param markdown any valid markdown
11928
+ * @returns code block with language and content
11929
+ * @public exported from `@promptbook/markdown-utils`
11930
+ * @throws {ParseError} if there is not exactly one code block in the markdown
11931
+ */
11932
+ function extractOneBlockFromMarkdown(markdown) {
11933
+ const codeBlocks = extractAllBlocksFromMarkdown(markdown);
11934
+ if (codeBlocks.length !== 1) {
11935
+ throw new ParseError(spaceTrim$2((block) => `
11936
+ There should be exactly 1 code block in task section, found ${codeBlocks.length} code blocks
11937
+
11938
+ ${block(codeBlocks.map((block, i) => `Block ${i + 1}:\n${block.content}`).join('\n\n\n'))}
11939
+ `));
11940
+ }
11941
+ return codeBlocks[0];
11942
+ }
11943
+ /***
11944
+ * TODO: [🍓][🌻] Decide of this is internal utility, external util OR validator/postprocessor
11945
+ */
11946
+
11947
+ /**
11948
+ * Extracts code block from markdown.
11949
+ *
11950
+ * - When there are multiple or no code blocks the function throws a `ParseError`
11951
+ *
11952
+ * Note: There are multiple similar function:
11953
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
11954
+ * - `extractJsonBlock` extracts exactly one valid JSON code block
11955
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
11956
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
11957
+ *
11958
+ * @public exported from `@promptbook/markdown-utils`
11959
+ * @throws {ParseError} if there is not exactly one code block in the markdown
11960
+ */
11961
+ function extractBlock(markdown) {
11962
+ const { content } = extractOneBlockFromMarkdown(markdown);
11963
+ return content;
11964
+ }
11965
+
11966
+ /**
11967
+ * Function trimCodeBlock will trim starting and ending code block from the string if it is present.
11968
+ *
11969
+ * Note: [🔂] This function is idempotent.
11970
+ * Note: This is useful for post-processing of the result of the chat LLM model
11971
+ * when the model wraps the result in the (markdown) code block.
11972
+ *
11973
+ * @public exported from `@promptbook/markdown-utils`
11974
+ */
11975
+ function trimCodeBlock(value) {
11976
+ value = spaceTrim$1(value);
11977
+ if (!/^```[a-z]*(.*)```$/is.test(value)) {
11978
+ return value;
11979
+ }
11980
+ value = value.replace(/^```[a-z]*/i, '');
11981
+ value = value.replace(/```$/i, '');
11982
+ value = spaceTrim$1(value);
11983
+ return value;
11984
+ }
11985
+
11986
+ /**
11987
+ * Function trimEndOfCodeBlock will remove ending code block from the string if it is present.
11988
+ *
11989
+ * Note: This is useful for post-processing of the result of the completion LLM model
11990
+ * if you want to start code block in the prompt but you don't want to end it in the result.
11991
+ *
11992
+ * @public exported from `@promptbook/markdown-utils`
11993
+ */
11994
+ function trimEndOfCodeBlock(value) {
11995
+ value = spaceTrim$1(value);
11996
+ value = value.replace(/```$/g, '');
11997
+ value = spaceTrim$1(value);
11998
+ return value;
11999
+ }
12000
+
12001
+ /**
12002
+ * @private internal for `preserve`
12003
+ */
12004
+ const _preserved = [];
12005
+ /**
12006
+ * Does nothing, but preserves the function in the bundle
12007
+ * Compiler is tricked into thinking the function is used
12008
+ *
12009
+ * @param value any function to preserve
12010
+ * @returns nothing
12011
+ * @private within the repository
12012
+ */
12013
+ function $preserve(...value) {
12014
+ _preserved.push(...value);
12015
+ }
12016
+ /**
12017
+ * Note: [💞] Ignore a discrepancy between file name and entity name
12018
+ */
12019
+
12020
+ // Note: [💎]
12021
+ /**
12022
+ * ScriptExecutionTools for JavaScript implemented via eval
12023
+ *
12024
+ * Warning: It is used for testing and mocking
12025
+ * **NOT intended to use in the production** due to its unsafe nature, use `JavascriptExecutionTools` instead.
12026
+ *
12027
+ * @public exported from `@promptbook/javascript`
12028
+ */
12029
+ class JavascriptEvalExecutionTools {
12030
+ constructor(options) {
12031
+ this.options = options || {};
12032
+ }
12033
+ /**
12034
+ * Executes a JavaScript
12035
+ */
12036
+ async execute(options) {
12037
+ const { scriptLanguage, parameters } = options;
12038
+ let { script } = options;
12039
+ if (scriptLanguage !== 'javascript') {
12040
+ throw new PipelineExecutionError(`Script language ${scriptLanguage} not supported to be executed by JavascriptEvalExecutionTools`);
12041
+ }
12042
+ // Note: [💎]
12043
+ // Note: Using direct eval, following variables are in same scope as eval call so they are accessible from inside the evaluated script:
12044
+ const spaceTrim = (_) => spaceTrim$2(_);
12045
+ $preserve(spaceTrim);
8320
12046
  const removeQuotes$1 = removeQuotes;
8321
12047
  $preserve(removeQuotes$1);
8322
12048
  const unwrapResult$1 = unwrapResult;
@@ -8398,6 +12124,13 @@ class JavascriptEvalExecutionTools {
8398
12124
  `const ${functionName} = buildinFunctions.${functionName};`)
8399
12125
  .join('\n');
8400
12126
  // TODO: DRY [🍯]
12127
+ const commitmentsFunctions = getAllCommitmentsToolFunctions();
12128
+ const commitmentsFunctionsStatement = Object.keys(commitmentsFunctions)
12129
+ .map((functionName) =>
12130
+ // Note: Custom functions are exposed to the current scope as variables
12131
+ `const ${functionName} = commitmentsFunctions.${functionName};`)
12132
+ .join('\n');
12133
+ // TODO: DRY [🍯]
8401
12134
  const customFunctions = this.options.functions || {};
8402
12135
  const customFunctionsStatement = Object.keys(customFunctions)
8403
12136
  .map((functionName) =>
@@ -8411,6 +12144,10 @@ class JavascriptEvalExecutionTools {
8411
12144
  // Build-in functions:
8412
12145
  ${block(buildinFunctionsStatement)}
8413
12146
 
12147
+ // Commitments functions:
12148
+ ${block(commitmentsFunctionsStatement)}
12149
+
12150
+
8414
12151
  // Custom functions:
8415
12152
  ${block(customFunctionsStatement || '// -- No custom functions --')}
8416
12153
 
@@ -8418,7 +12155,7 @@ class JavascriptEvalExecutionTools {
8418
12155
  ${block(Object.entries(parameters)
8419
12156
  .map(([key, value]) => `const ${key} = ${JSON.stringify(value)};`)
8420
12157
  .join('\n'))}
8421
- (()=>{ ${script} })()
12158
+ (async ()=>{ ${script} })()
8422
12159
  `);
8423
12160
  if (this.options.isVerbose) {
8424
12161
  console.info(spaceTrim$2((block) => `