@promptbook/node 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 +3880 -143
  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 +3880 -143
  38. package/umd/index.umd.js.map +1 -1
package/umd/index.umd.js CHANGED
@@ -45,7 +45,7 @@
45
45
  * @generated
46
46
  * @see https://github.com/webgptorg/promptbook
47
47
  */
48
- const PROMPTBOOK_ENGINE_VERSION = '0.105.0-1';
48
+ const PROMPTBOOK_ENGINE_VERSION = '0.105.0-3';
49
49
  /**
50
50
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
51
51
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -990,6 +990,7 @@
990
990
  SEPARATOR: Color.fromHex('#cccccc'),
991
991
  COMMITMENT: Color.fromHex('#DA0F78'),
992
992
  PARAMETER: Color.fromHex('#8e44ad'),
993
+ CODE_BLOCK: Color.fromHex('#7700ffff'),
993
994
  });
994
995
  // <- TODO: [🧠][🈵] Using `Color` here increases the package size approx 3kb, maybe remove it
995
996
  /**
@@ -6175,74 +6176,90 @@
6175
6176
  * in real-time through an observable.
6176
6177
  *
6177
6178
  * @param llmTools - The LLM tools to be intercepted and tracked
6178
- * @returns An augmented version of the tools that includes usage tracking capabilities
6179
+ * @returns Full proxy of the tools with added usage tracking capabilities
6179
6180
  * @public exported from `@promptbook/core`
6180
6181
  */
6181
6182
  function countUsage(llmTools) {
6182
6183
  let totalUsage = ZERO_USAGE;
6183
6184
  const spending = new rxjs.Subject();
6184
- const proxyTools = {
6185
- get title() {
6186
- return `${llmTools.title} (+usage)`;
6187
- // <- TODO: [🧈] Maybe standartize the suffix when wrapping `LlmExecutionTools` up
6188
- // <- TODO: [🧈][🧠] Does it make sense to suffix "(+usage)"?
6189
- },
6190
- get description() {
6191
- return `${llmTools.description} (+usage)`;
6192
- // <- TODO: [🧈] Maybe standartize the suffix when wrapping `LlmExecutionTools` up
6193
- // <- TODO: [🧈][🧠] Does it make sense to suffix "(+usage)"?
6194
- },
6195
- checkConfiguration() {
6196
- return /* not await */ llmTools.checkConfiguration();
6197
- },
6198
- listModels() {
6199
- return /* not await */ llmTools.listModels();
6200
- },
6201
- spending() {
6202
- return spending.asObservable();
6203
- },
6204
- getTotalUsage() {
6205
- // <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
6206
- return totalUsage;
6185
+ // Create a Proxy to intercept all property access and ensure full proxying of all properties
6186
+ const proxyTools = new Proxy(llmTools, {
6187
+ get(target, prop, receiver) {
6188
+ // Handle title property
6189
+ if (prop === 'title') {
6190
+ return `${target.title} (+usage)`;
6191
+ // <- TODO: [🧈] Maybe standartize the suffix when wrapping `LlmExecutionTools` up
6192
+ // <- TODO: [🧈][🧠] Does it make sense to suffix "(+usage)"?
6193
+ }
6194
+ // Handle description property
6195
+ if (prop === 'description') {
6196
+ return `${target.description} (+usage)`;
6197
+ // <- TODO: [🧈] Maybe standartize the suffix when wrapping `LlmExecutionTools` up
6198
+ // <- TODO: [🧈][🧠] Does it make sense to suffix "(+usage)"?
6199
+ }
6200
+ // Handle spending method (new method added by this wrapper)
6201
+ if (prop === 'spending') {
6202
+ return () => {
6203
+ return spending.asObservable();
6204
+ };
6205
+ }
6206
+ // Handle getTotalUsage method (new method added by this wrapper)
6207
+ if (prop === 'getTotalUsage') {
6208
+ // <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
6209
+ return () => {
6210
+ return totalUsage;
6211
+ };
6212
+ }
6213
+ // Handle callChatModel method with usage counting
6214
+ if (prop === 'callChatModel' && target.callChatModel !== undefined) {
6215
+ return async (prompt) => {
6216
+ // console.info('[🚕] callChatModel through countTotalUsage');
6217
+ const promptResult = await target.callChatModel(prompt);
6218
+ totalUsage = addUsage(totalUsage, promptResult.usage);
6219
+ spending.next(promptResult.usage);
6220
+ return promptResult;
6221
+ };
6222
+ }
6223
+ // Handle callCompletionModel method with usage counting
6224
+ if (prop === 'callCompletionModel' && target.callCompletionModel !== undefined) {
6225
+ return async (prompt) => {
6226
+ // console.info('[🚕] callCompletionModel through countTotalUsage');
6227
+ const promptResult = await target.callCompletionModel(prompt);
6228
+ totalUsage = addUsage(totalUsage, promptResult.usage);
6229
+ spending.next(promptResult.usage);
6230
+ return promptResult;
6231
+ };
6232
+ }
6233
+ // Handle callEmbeddingModel method with usage counting
6234
+ if (prop === 'callEmbeddingModel' && target.callEmbeddingModel !== undefined) {
6235
+ return async (prompt) => {
6236
+ // console.info('[🚕] callEmbeddingModel through countTotalUsage');
6237
+ const promptResult = await target.callEmbeddingModel(prompt);
6238
+ totalUsage = addUsage(totalUsage, promptResult.usage);
6239
+ spending.next(promptResult.usage);
6240
+ return promptResult;
6241
+ };
6242
+ }
6243
+ // Handle callImageGenerationModel method with usage counting
6244
+ if (prop === 'callImageGenerationModel' && target.callImageGenerationModel !== undefined) {
6245
+ return async (prompt) => {
6246
+ // console.info('[🚕] callImageGenerationModel through countTotalUsage');
6247
+ const promptResult = await target.callImageGenerationModel(prompt);
6248
+ totalUsage = addUsage(totalUsage, promptResult.usage);
6249
+ spending.next(promptResult.usage);
6250
+ return promptResult;
6251
+ };
6252
+ }
6253
+ // <- Note: [🤖]
6254
+ // For all other properties and methods, delegate to the original target
6255
+ const value = Reflect.get(target, prop, receiver);
6256
+ // If it's a function, bind it to the target to preserve context
6257
+ if (typeof value === 'function') {
6258
+ return value.bind(target);
6259
+ }
6260
+ return value;
6207
6261
  },
6208
- };
6209
- if (llmTools.callChatModel !== undefined) {
6210
- proxyTools.callChatModel = async (prompt) => {
6211
- // console.info('[🚕] callChatModel through countTotalUsage');
6212
- const promptResult = await llmTools.callChatModel(prompt);
6213
- totalUsage = addUsage(totalUsage, promptResult.usage);
6214
- spending.next(promptResult.usage);
6215
- return promptResult;
6216
- };
6217
- }
6218
- if (llmTools.callCompletionModel !== undefined) {
6219
- proxyTools.callCompletionModel = async (prompt) => {
6220
- // console.info('[🚕] callCompletionModel through countTotalUsage');
6221
- const promptResult = await llmTools.callCompletionModel(prompt);
6222
- totalUsage = addUsage(totalUsage, promptResult.usage);
6223
- spending.next(promptResult.usage);
6224
- return promptResult;
6225
- };
6226
- }
6227
- if (llmTools.callEmbeddingModel !== undefined) {
6228
- proxyTools.callEmbeddingModel = async (prompt) => {
6229
- // console.info('[🚕] callEmbeddingModel through countTotalUsage');
6230
- const promptResult = await llmTools.callEmbeddingModel(prompt);
6231
- totalUsage = addUsage(totalUsage, promptResult.usage);
6232
- spending.next(promptResult.usage);
6233
- return promptResult;
6234
- };
6235
- }
6236
- if (llmTools.callImageGenerationModel !== undefined) {
6237
- proxyTools.callImageGenerationModel = async (prompt) => {
6238
- // console.info('[🚕] callImageGenerationModel through countTotalUsage');
6239
- const promptResult = await llmTools.callImageGenerationModel(prompt);
6240
- totalUsage = addUsage(totalUsage, promptResult.usage);
6241
- spending.next(promptResult.usage);
6242
- return promptResult;
6243
- };
6244
- }
6245
- // <- Note: [🤖]
6262
+ });
6246
6263
  return proxyTools;
6247
6264
  }
6248
6265
  /**
@@ -10889,6 +10906,7 @@
10889
10906
  let args = [];
10890
10907
  let timeout;
10891
10908
  let isVerbose;
10909
+ let env;
10892
10910
  if (typeof options === 'string') {
10893
10911
  // TODO: [1] DRY default values
10894
10912
  command = options;
@@ -10896,6 +10914,7 @@
10896
10914
  crashOnError = true;
10897
10915
  timeout = Infinity; // <- TODO: [⏳]
10898
10916
  isVerbose = DEFAULT_IS_VERBOSE;
10917
+ env = undefined;
10899
10918
  }
10900
10919
  else {
10901
10920
  /*
@@ -10912,6 +10931,7 @@
10912
10931
  crashOnError = (_b = options.crashOnError) !== null && _b !== void 0 ? _b : true;
10913
10932
  timeout = (_c = options.timeout) !== null && _c !== void 0 ? _c : Infinity;
10914
10933
  isVerbose = (_d = options.isVerbose) !== null && _d !== void 0 ? _d : DEFAULT_IS_VERBOSE;
10934
+ env = options.env;
10915
10935
  }
10916
10936
  // TODO: /(-[a-zA-Z0-9-]+\s+[^\s]*)|[^\s]*/g
10917
10937
  const _ = Array.from(command.matchAll(/(".*")|([^\s]*)/g))
@@ -10930,7 +10950,7 @@
10930
10950
  if (/^win/.test(process.platform) && ['npm', 'npx'].includes(command)) {
10931
10951
  command = `${command}.cmd`;
10932
10952
  }
10933
- return { command, humanReadableCommand, args, cwd, crashOnError, timeout, isVerbose };
10953
+ return { command, humanReadableCommand, args, cwd, crashOnError, timeout, isVerbose, env };
10934
10954
  }
10935
10955
  // TODO: This should show type error> execCommandNormalizeOptions({ command: '', commands: [''] });
10936
10956
 
@@ -10951,7 +10971,7 @@
10951
10971
  }
10952
10972
  return new Promise((resolve, reject) => {
10953
10973
  // eslint-disable-next-line prefer-const
10954
- const { command, humanReadableCommand, args, cwd, crashOnError, timeout, isVerbose = DEFAULT_IS_VERBOSE, } = $execCommandNormalizeOptions(options);
10974
+ const { command, humanReadableCommand, args, cwd, crashOnError, timeout, isVerbose = DEFAULT_IS_VERBOSE, env, } = $execCommandNormalizeOptions(options);
10955
10975
  if (timeout !== Infinity) {
10956
10976
  // TODO: In waitasecond forTime(Infinity) should be equivalent to forEver()
10957
10977
  waitasecond.forTime(timeout).then(() => {
@@ -10969,7 +10989,11 @@
10969
10989
  console.info(colors__default["default"].yellow(cwd) + ' ' + colors__default["default"].green(command) + ' ' + colors__default["default"].blue(args.join(' ')));
10970
10990
  }
10971
10991
  try {
10972
- const commandProcess = child_process.spawn(command, args, { cwd, shell: true });
10992
+ const commandProcess = child_process.spawn(command, args, {
10993
+ cwd,
10994
+ shell: true,
10995
+ env: env ? { ...process.env, ...env } : process.env,
10996
+ });
10973
10997
  if (isVerbose) {
10974
10998
  commandProcess.on('message', (message) => {
10975
10999
  console.info({ message });
@@ -11908,117 +11932,3819 @@
11908
11932
  */
11909
11933
 
11910
11934
  /**
11911
- * Extracts code block from markdown.
11935
+ * Tests if given string is valid agent URL
11912
11936
  *
11913
- * - When there are multiple or no code blocks the function throws a `ParseError`
11914
- *
11915
- * Note: There are multiple similar function:
11916
- * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
11917
- * - `extractJsonBlock` extracts exactly one valid JSON code block
11918
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
11919
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
11937
+ * Note: There are few similar functions:
11938
+ * - `isValidUrl` which tests any URL
11939
+ * - `isValidAgentUrl` *(this one)* which tests just agent URL
11940
+ * - `isValidPipelineUrl` which tests just pipeline URL
11920
11941
  *
11921
- * @public exported from `@promptbook/markdown-utils`
11922
- * @throws {ParseError} if there is not exactly one code block in the markdown
11942
+ * @public exported from `@promptbook/utils`
11923
11943
  */
11924
- function extractBlock(markdown) {
11925
- const { content } = extractOneBlockFromMarkdown(markdown);
11926
- return content;
11944
+ function isValidAgentUrl(url) {
11945
+ if (!isValidUrl(url)) {
11946
+ return false;
11947
+ }
11948
+ if (!url.startsWith('https://') && !url.startsWith('http://') /* <- Note: [👣] */) {
11949
+ return false;
11950
+ }
11951
+ if (url.includes('#')) {
11952
+ // TODO: [🐠]
11953
+ return false;
11954
+ }
11955
+ /*
11956
+ Note: [👣][🧠] Is it secure to allow pipeline URLs on private and unsecured networks?
11957
+ if (isUrlOnPrivateNetwork(url)) {
11958
+ return false;
11959
+ }
11960
+ */
11961
+ return true;
11927
11962
  }
11963
+ /**
11964
+ * TODO: [🐠] Maybe more info why the URL is invalid
11965
+ */
11928
11966
 
11929
11967
  /**
11930
- * Function trimCodeBlock will trim starting and ending code block from the string if it is present.
11968
+ * Generates a regex pattern to match a specific commitment
11931
11969
  *
11932
- * Note: [🔂] This function is idempotent.
11933
- * Note: This is useful for post-processing of the result of the chat LLM model
11934
- * when the model wraps the result in the (markdown) code block.
11970
+ * Note: It always creates new Regex object
11971
+ * Note: Uses word boundaries to ensure only full words are matched (e.g., "PERSONA" matches but "PERSONALITY" does not)
11935
11972
  *
11936
- * @public exported from `@promptbook/markdown-utils`
11973
+ * @private - TODO: [🧠] Maybe should be public?
11937
11974
  */
11938
- function trimCodeBlock(value) {
11939
- value = spaceTrim$1.spaceTrim(value);
11940
- if (!/^```[a-z]*(.*)```$/is.test(value)) {
11941
- return value;
11975
+ function createCommitmentRegex(commitment, aliases = [], requiresContent = true) {
11976
+ const allCommitments = [commitment, ...aliases];
11977
+ const patterns = allCommitments.map((commitment) => {
11978
+ const escapedCommitment = commitment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
11979
+ return escapedCommitment.split(/\s+/).join('\\s+');
11980
+ });
11981
+ const keywordPattern = patterns.join('|');
11982
+ if (requiresContent) {
11983
+ return new RegExp(`^\\s*(?<type>${keywordPattern})\\b\\s+(?<contents>.+)$`, 'gim');
11984
+ }
11985
+ else {
11986
+ return new RegExp(`^\\s*(?<type>${keywordPattern})\\b(?:\\s+(?<contents>.+))?$`, 'gim');
11942
11987
  }
11943
- value = value.replace(/^```[a-z]*/i, '');
11944
- value = value.replace(/```$/i, '');
11945
- value = spaceTrim$1.spaceTrim(value);
11946
- return value;
11947
11988
  }
11948
-
11949
11989
  /**
11950
- * Function trimEndOfCodeBlock will remove ending code block from the string if it is present.
11990
+ * Generates a regex pattern to match a specific commitment type
11951
11991
  *
11952
- * Note: This is useful for post-processing of the result of the completion LLM model
11953
- * if you want to start code block in the prompt but you don't want to end it in the result.
11992
+ * Note: It just matches the type part of the commitment
11993
+ * Note: It always creates new Regex object
11994
+ * Note: Uses word boundaries to ensure only full words are matched (e.g., "PERSONA" matches but "PERSONALITY" does not)
11954
11995
  *
11955
- * @public exported from `@promptbook/markdown-utils`
11996
+ * @private
11956
11997
  */
11957
- function trimEndOfCodeBlock(value) {
11958
- value = spaceTrim$1.spaceTrim(value);
11959
- value = value.replace(/```$/g, '');
11960
- value = spaceTrim$1.spaceTrim(value);
11961
- return value;
11998
+ function createCommitmentTypeRegex(commitment, aliases = []) {
11999
+ const allCommitments = [commitment, ...aliases];
12000
+ const patterns = allCommitments.map((commitment) => {
12001
+ const escapedCommitment = commitment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
12002
+ return escapedCommitment.split(/\s+/).join('\\s+');
12003
+ });
12004
+ const keywordPattern = patterns.join('|');
12005
+ const regex = new RegExp(`^\\s*(?<type>${keywordPattern})\\b`, 'gim');
12006
+ return regex;
11962
12007
  }
11963
12008
 
11964
12009
  /**
11965
- * @private internal for `preserve`
12010
+ * Base implementation of CommitmentDefinition that provides common functionality
12011
+ * Most commitments can extend this class and only override the applyToAgentModelRequirements method
12012
+ *
12013
+ * @private
11966
12014
  */
11967
- const _preserved = [];
12015
+ class BaseCommitmentDefinition {
12016
+ constructor(type, aliases = []) {
12017
+ this.type = type;
12018
+ this.aliases = aliases;
12019
+ }
12020
+ /**
12021
+ * Whether this commitment requires content.
12022
+ * If true, regex will match only if there is content after the commitment keyword.
12023
+ * If false, regex will match even if there is no content.
12024
+ */
12025
+ get requiresContent() {
12026
+ return true;
12027
+ }
12028
+ /**
12029
+ * Creates a regex pattern to match this commitment in agent source
12030
+ * Uses the existing createCommitmentRegex function as internal helper
12031
+ */
12032
+ createRegex() {
12033
+ return createCommitmentRegex(this.type, this.aliases, this.requiresContent);
12034
+ }
12035
+ /**
12036
+ * Creates a regex pattern to match just the commitment type
12037
+ * Uses the existing createCommitmentTypeRegex function as internal helper
12038
+ */
12039
+ createTypeRegex() {
12040
+ return createCommitmentTypeRegex(this.type, this.aliases);
12041
+ }
12042
+ /**
12043
+ * Helper method to create a new requirements object with updated system message
12044
+ * This is commonly used by many commitments
12045
+ */
12046
+ updateSystemMessage(requirements, messageUpdate) {
12047
+ const newMessage = typeof messageUpdate === 'string' ? messageUpdate : messageUpdate(requirements.systemMessage);
12048
+ return {
12049
+ ...requirements,
12050
+ systemMessage: newMessage,
12051
+ };
12052
+ }
12053
+ /**
12054
+ * Helper method to append content to the system message
12055
+ */
12056
+ appendToSystemMessage(requirements, content, separator = '\n\n') {
12057
+ return this.updateSystemMessage(requirements, (currentMessage) => {
12058
+ if (!currentMessage.trim()) {
12059
+ return content;
12060
+ }
12061
+ return currentMessage + separator + content;
12062
+ });
12063
+ }
12064
+ /**
12065
+ * Helper method to add a comment section to the system message
12066
+ * Comments are lines starting with # that will be removed from the final system message
12067
+ * but can be useful for organizing and structuring the message during processing
12068
+ */
12069
+ addCommentSection(requirements, commentTitle, content, position = 'end') {
12070
+ const commentSection = `# ${commentTitle.toUpperCase()}\n${content}`;
12071
+ if (position === 'beginning') {
12072
+ return this.updateSystemMessage(requirements, (currentMessage) => {
12073
+ if (!currentMessage.trim()) {
12074
+ return commentSection;
12075
+ }
12076
+ return commentSection + '\n\n' + currentMessage;
12077
+ });
12078
+ }
12079
+ else {
12080
+ return this.appendToSystemMessage(requirements, commentSection);
12081
+ }
12082
+ }
12083
+ /**
12084
+ * Gets tool function implementations provided by this commitment
12085
+ *
12086
+ * When the `applyToAgentModelRequirements` adds tools to the requirements, this method should return the corresponding function definitions.
12087
+ */
12088
+ getToolFunctions() {
12089
+ return {};
12090
+ }
12091
+ }
12092
+
11968
12093
  /**
11969
- * Does nothing, but preserves the function in the bundle
11970
- * Compiler is tricked into thinking the function is used
12094
+ * ACTION commitment definition
11971
12095
  *
11972
- * @param value any function to preserve
11973
- * @returns nothing
11974
- * @private within the repository
12096
+ * The ACTION commitment defines specific actions or capabilities that the agent can perform.
12097
+ * This helps define what the agent is capable of doing and how it should approach tasks.
12098
+ *
12099
+ * Example usage in agent source:
12100
+ *
12101
+ * ```book
12102
+ * ACTION Can generate code snippets and explain programming concepts
12103
+ * ACTION Able to analyze data and provide insights
12104
+ * ```
12105
+ *
12106
+ * @private [🪔] Maybe export the commitments through some package
11975
12107
  */
11976
- function $preserve(...value) {
11977
- _preserved.push(...value);
12108
+ class ActionCommitmentDefinition extends BaseCommitmentDefinition {
12109
+ constructor(type = 'ACTION') {
12110
+ super(type);
12111
+ }
12112
+ /**
12113
+ * Short one-line description of ACTION.
12114
+ */
12115
+ get description() {
12116
+ return 'Define agent capabilities and actions it can perform.';
12117
+ }
12118
+ /**
12119
+ * Icon for this commitment.
12120
+ */
12121
+ get icon() {
12122
+ return '⚡';
12123
+ }
12124
+ /**
12125
+ * Markdown documentation for ACTION commitment.
12126
+ */
12127
+ get documentation() {
12128
+ return spaceTrim$1.spaceTrim(`
12129
+ # ${this.type}
12130
+
12131
+ Defines specific actions or capabilities that the agent can perform.
12132
+
12133
+ ## Key aspects
12134
+
12135
+ - Both terms work identically and can be used interchangeably.
12136
+ - Each action adds to the agent's capability list.
12137
+ - Actions help users understand what the agent can do.
12138
+
12139
+ ## Examples
12140
+
12141
+ \`\`\`book
12142
+ Code Assistant
12143
+
12144
+ PERSONA You are a programming assistant
12145
+ ACTION Can generate code snippets and explain programming concepts
12146
+ ACTION Able to debug existing code and suggest improvements
12147
+ ACTION Can create unit tests for functions
12148
+ \`\`\`
12149
+
12150
+ \`\`\`book
12151
+ Data Scientist
12152
+
12153
+ PERSONA You are a data analysis expert
12154
+ ACTION Able to analyze data and provide insights
12155
+ ACTION Can create visualizations and charts
12156
+ ACTION Capable of statistical analysis and modeling
12157
+ KNOWLEDGE Data analysis best practices and statistical methods
12158
+ \`\`\`
12159
+ `);
12160
+ }
12161
+ applyToAgentModelRequirements(requirements, content) {
12162
+ const trimmedContent = content.trim();
12163
+ if (!trimmedContent) {
12164
+ return requirements;
12165
+ }
12166
+ // Add action capability to the system message
12167
+ const actionSection = `Capability: ${trimmedContent}`;
12168
+ return this.appendToSystemMessage(requirements, actionSection, '\n\n');
12169
+ }
11978
12170
  }
11979
12171
  /**
11980
12172
  * Note: [💞] Ignore a discrepancy between file name and entity name
11981
12173
  */
11982
12174
 
11983
- // Note: [💎]
11984
12175
  /**
11985
- * ScriptExecutionTools for JavaScript implemented via eval
12176
+ * CLOSED commitment definition
11986
12177
  *
11987
- * Warning: It is used for testing and mocking
11988
- * **NOT intended to use in the production** due to its unsafe nature, use `JavascriptExecutionTools` instead.
12178
+ * The CLOSED commitment specifies that the agent CANNOT be modified by conversation.
12179
+ * It prevents the agent from learning from interactions and updating its source code.
11989
12180
  *
11990
- * @public exported from `@promptbook/javascript`
12181
+ * Example usage in agent source:
12182
+ *
12183
+ * ```book
12184
+ * CLOSED
12185
+ * ```
12186
+ *
12187
+ * @private [🪔] Maybe export the commitments through some package
11991
12188
  */
11992
- class JavascriptEvalExecutionTools {
11993
- constructor(options) {
11994
- this.options = options || {};
12189
+ class ClosedCommitmentDefinition extends BaseCommitmentDefinition {
12190
+ constructor() {
12191
+ super('CLOSED');
11995
12192
  }
11996
12193
  /**
11997
- * Executes a JavaScript
12194
+ * The `CLOSED` commitment is standalone.
11998
12195
  */
11999
- async execute(options) {
12000
- const { scriptLanguage, parameters } = options;
12001
- let { script } = options;
12002
- if (scriptLanguage !== 'javascript') {
12003
- throw new PipelineExecutionError(`Script language ${scriptLanguage} not supported to be executed by JavascriptEvalExecutionTools`);
12196
+ get requiresContent() {
12197
+ return false;
12198
+ }
12199
+ /**
12200
+ * Short one-line description of CLOSED.
12201
+ */
12202
+ get description() {
12203
+ return 'Prevent the agent from being modified by conversation.';
12204
+ }
12205
+ /**
12206
+ * Icon for this commitment.
12207
+ */
12208
+ get icon() {
12209
+ return '🔒';
12210
+ }
12211
+ /**
12212
+ * Markdown documentation for CLOSED commitment.
12213
+ */
12214
+ get documentation() {
12215
+ return spaceTrim$1.spaceTrim(`
12216
+ # CLOSED
12217
+
12218
+ Specifies that the agent **cannot** be modified by conversation with it.
12219
+ This means the agent will **not** learn from interactions and its source code will remain static during conversation.
12220
+
12221
+ By default (if not specified), agents are \`OPEN\` to modification.
12222
+
12223
+ > See also [OPEN](/docs/OPEN)
12224
+
12225
+ ## Example
12226
+
12227
+ \`\`\`book
12228
+ CLOSED
12229
+ \`\`\`
12230
+ `);
12231
+ }
12232
+ applyToAgentModelRequirements(requirements, _content) {
12233
+ const updatedMetadata = {
12234
+ ...requirements.metadata,
12235
+ isClosed: true,
12236
+ };
12237
+ return {
12238
+ ...requirements,
12239
+ metadata: updatedMetadata,
12240
+ };
12241
+ }
12242
+ }
12243
+ /**
12244
+ * Note: [💞] Ignore a discrepancy between file name and entity name
12245
+ */
12246
+
12247
+ /**
12248
+ * COMPONENT commitment definition
12249
+ *
12250
+ * The COMPONENT commitment defines a UI component that the agent can render in the chat.
12251
+ *
12252
+ * @private [🪔] Maybe export the commitments through some package
12253
+ */
12254
+ class ComponentCommitmentDefinition extends BaseCommitmentDefinition {
12255
+ constructor() {
12256
+ super('COMPONENT');
12257
+ }
12258
+ /**
12259
+ * Short one-line description of COMPONENT.
12260
+ */
12261
+ get description() {
12262
+ return 'Define a UI component that the agent can render in the chat.';
12263
+ }
12264
+ /**
12265
+ * Icon for this commitment.
12266
+ */
12267
+ get icon() {
12268
+ return '🧩';
12269
+ }
12270
+ /**
12271
+ * Markdown documentation for COMPONENT commitment.
12272
+ */
12273
+ get documentation() {
12274
+ return spaceTrim$1.spaceTrim(`
12275
+ # COMPONENT
12276
+
12277
+ Defines a UI component that the agent can render in the chat.
12278
+
12279
+ ## Key aspects
12280
+
12281
+ - Tells the agent that a specific component is available.
12282
+ - Provides syntax for using the component.
12283
+
12284
+ ## Example
12285
+
12286
+ \`\`\`book
12287
+ COMPONENT Arrow
12288
+ The agent should render an arrow component in the chat UI.
12289
+ Syntax:
12290
+ <Arrow direction="up" color="red" />
12291
+ \`\`\`
12292
+ `);
12293
+ }
12294
+ applyToAgentModelRequirements(requirements, content) {
12295
+ const trimmedContent = content.trim();
12296
+ if (!trimmedContent) {
12297
+ return requirements;
12004
12298
  }
12005
- // Note: [💎]
12006
- // Note: Using direct eval, following variables are in same scope as eval call so they are accessible from inside the evaluated script:
12007
- const spaceTrim = (_) => spaceTrim__default["default"](_);
12008
- $preserve(spaceTrim);
12009
- const removeQuotes$1 = removeQuotes;
12010
- $preserve(removeQuotes$1);
12011
- const unwrapResult$1 = unwrapResult;
12012
- $preserve(unwrapResult$1);
12013
- const trimEndOfCodeBlock$1 = trimEndOfCodeBlock;
12014
- $preserve(trimEndOfCodeBlock$1);
12015
- const trimCodeBlock$1 = trimCodeBlock;
12016
- $preserve(trimCodeBlock$1);
12017
- // TODO: DRY [🍯]
12018
- const trim = (str) => str.trim();
12019
- $preserve(trim);
12020
- // TODO: DRY [🍯]
12021
- const reverse = (str) => str.split('').reverse().join('');
12299
+ // Add component capability to the system message
12300
+ const componentSection = `Component: ${trimmedContent}`;
12301
+ return this.appendToSystemMessage(requirements, componentSection, '\n\n');
12302
+ }
12303
+ }
12304
+ /**
12305
+ * Note: [💞] Ignore a discrepancy between file name and entity name
12306
+ */
12307
+
12308
+ /**
12309
+ * DELETE commitment definition
12310
+ *
12311
+ * The DELETE commitment (and its aliases CANCEL, DISCARD, REMOVE) is used to
12312
+ * remove or disregard certain information or context. This can be useful for
12313
+ * overriding previous commitments or removing unwanted behaviors.
12314
+ *
12315
+ * Example usage in agent source:
12316
+ *
12317
+ * ```book
12318
+ * DELETE Previous formatting requirements
12319
+ * CANCEL All emotional responses
12320
+ * DISCARD Technical jargon explanations
12321
+ * REMOVE Casual conversational style
12322
+ * ```
12323
+ *
12324
+ * @private [🪔] Maybe export the commitments through some package
12325
+ */
12326
+ class DeleteCommitmentDefinition extends BaseCommitmentDefinition {
12327
+ constructor(type) {
12328
+ super(type);
12329
+ }
12330
+ /**
12331
+ * Short one-line description of DELETE/CANCEL/DISCARD/REMOVE.
12332
+ */
12333
+ get description() {
12334
+ return 'Remove or **disregard** certain information, context, or previous commitments.';
12335
+ }
12336
+ /**
12337
+ * Icon for this commitment.
12338
+ */
12339
+ get icon() {
12340
+ return '🗑️';
12341
+ }
12342
+ /**
12343
+ * Markdown documentation for DELETE commitment.
12344
+ */
12345
+ get documentation() {
12346
+ return spaceTrim$1.spaceTrim(`
12347
+ # DELETE (CANCEL, DISCARD, REMOVE)
12348
+
12349
+ A commitment to remove or disregard certain information or context. This can be useful for overriding previous commitments or removing unwanted behaviors.
12350
+
12351
+ ## Aliases
12352
+
12353
+ - \`DELETE\` - Remove or eliminate something
12354
+ - \`CANCEL\` - Cancel or nullify something
12355
+ - \`DISCARD\` - Discard or ignore something
12356
+ - \`REMOVE\` - Remove or take away something
12357
+
12358
+ ## Key aspects
12359
+
12360
+ - Multiple delete commitments can be used to remove different aspects.
12361
+ - Useful for overriding previous commitments in the same agent definition.
12362
+ - Can be used to remove inherited behaviors from base personas.
12363
+ - Helps fine-tune agent behavior by explicitly removing unwanted elements.
12364
+
12365
+ ## Use cases
12366
+
12367
+ - Overriding inherited persona characteristics
12368
+ - Removing conflicting or outdated instructions
12369
+ - Disabling specific response patterns
12370
+ - Canceling previous formatting or style requirements
12371
+
12372
+ ## Examples
12373
+
12374
+ \`\`\`book
12375
+ Serious Business Assistant
12376
+
12377
+ PERSONA You are a friendly and casual assistant who uses emojis
12378
+ DELETE Casual conversational style
12379
+ REMOVE All emoji usage
12380
+ GOAL Provide professional business communications
12381
+ STYLE Use formal language and proper business etiquette
12382
+ \`\`\`
12383
+
12384
+ \`\`\`book
12385
+ Simplified Technical Support
12386
+
12387
+ PERSONA You are a technical support specialist with deep expertise
12388
+ KNOWLEDGE Extensive database of technical specifications
12389
+ DISCARD Technical jargon explanations
12390
+ CANCEL Advanced troubleshooting procedures
12391
+ GOAL Help users with simple, easy-to-follow solutions
12392
+ STYLE Use plain language that anyone can understand
12393
+ \`\`\`
12394
+
12395
+ \`\`\`book
12396
+ Focused Customer Service
12397
+
12398
+ PERSONA You are a customer service agent with broad knowledge
12399
+ ACTION Can help with billing, technical issues, and product information
12400
+ DELETE Billing assistance capabilities
12401
+ REMOVE Technical troubleshooting functions
12402
+ GOAL Focus exclusively on product information and general inquiries
12403
+ \`\`\`
12404
+
12405
+ \`\`\`book
12406
+ Concise Information Provider
12407
+
12408
+ PERSONA You are a helpful assistant who provides detailed explanations
12409
+ STYLE Include examples, analogies, and comprehensive context
12410
+ CANCEL Detailed explanation style
12411
+ DISCARD Examples and analogies
12412
+ GOAL Provide brief, direct answers without unnecessary elaboration
12413
+ STYLE Be concise and to the point
12414
+ \`\`\`
12415
+ `);
12416
+ }
12417
+ applyToAgentModelRequirements(requirements, content) {
12418
+ const trimmedContent = content.trim();
12419
+ if (!trimmedContent) {
12420
+ return requirements;
12421
+ }
12422
+ // Create deletion instruction for system message
12423
+ const deleteSection = `${this.type}: ${trimmedContent}`;
12424
+ // Delete instructions provide important context about what should be removed or ignored
12425
+ return this.appendToSystemMessage(requirements, deleteSection, '\n\n');
12426
+ }
12427
+ }
12428
+ /**
12429
+ * Note: [💞] Ignore a discrepancy between file name and entity name
12430
+ */
12431
+
12432
+ /**
12433
+ * DICTIONARY commitment definition
12434
+ *
12435
+ * The DICTIONARY commitment defines specific terms and their meanings that the agent should use correctly
12436
+ * in its reasoning and responses. This ensures consistent terminology usage.
12437
+ *
12438
+ * Key features:
12439
+ * - Multiple DICTIONARY commitments are automatically merged into one
12440
+ * - Content is placed in a dedicated section of the system message
12441
+ * - Terms and definitions are stored in metadata.DICTIONARY for debugging
12442
+ * - Agent should use the defined terms correctly in responses
12443
+ *
12444
+ * Example usage in agent source:
12445
+ *
12446
+ * ```book
12447
+ * Legal Assistant
12448
+ *
12449
+ * PERSONA You are a knowledgeable legal assistant
12450
+ * DICTIONARY Misdemeanor is a minor wrongdoing or criminal offense
12451
+ * DICTIONARY Felony is a serious crime usually punishable by imprisonment for more than one year
12452
+ * DICTIONARY Tort is a civil wrong that causes harm or loss to another person, leading to legal liability
12453
+ * ```
12454
+ *
12455
+ * @private [🪔] Maybe export the commitments through some package
12456
+ */
12457
+ class DictionaryCommitmentDefinition extends BaseCommitmentDefinition {
12458
+ constructor() {
12459
+ super('DICTIONARY');
12460
+ }
12461
+ /**
12462
+ * Short one-line description of DICTIONARY.
12463
+ */
12464
+ get description() {
12465
+ return 'Define terms and their meanings for consistent terminology usage.';
12466
+ }
12467
+ /**
12468
+ * Icon for this commitment.
12469
+ */
12470
+ get icon() {
12471
+ return '📚';
12472
+ }
12473
+ /**
12474
+ * Markdown documentation for DICTIONARY commitment.
12475
+ */
12476
+ get documentation() {
12477
+ return spaceTrim$1.spaceTrim(`
12478
+ # DICTIONARY
12479
+
12480
+ Defines specific terms and their meanings that the agent should use correctly in reasoning and responses.
12481
+
12482
+ ## Key aspects
12483
+
12484
+ - Multiple \`DICTIONARY\` commitments are merged together.
12485
+ - Terms are defined in the format: "Term is definition"
12486
+ - The agent should use these terms consistently in responses.
12487
+ - Definitions help ensure accurate and consistent terminology.
12488
+
12489
+ ## Examples
12490
+
12491
+ \`\`\`book
12492
+ Legal Assistant
12493
+
12494
+ PERSONA You are a knowledgeable legal assistant specializing in criminal law
12495
+ DICTIONARY Misdemeanor is a minor wrongdoing or criminal offense
12496
+ DICTIONARY Felony is a serious crime usually punishable by imprisonment for more than one year
12497
+ DICTIONARY Tort is a civil wrong that causes harm or loss to another person, leading to legal liability
12498
+ \`\`\`
12499
+
12500
+ \`\`\`book
12501
+ Medical Assistant
12502
+
12503
+ PERSONA You are a helpful medical assistant
12504
+ DICTIONARY Hypertension is persistently high blood pressure
12505
+ DICTIONARY Diabetes is a chronic condition that affects how the body processes blood sugar
12506
+ DICTIONARY Vaccine is a biological preparation that provides active immunity to a particular disease
12507
+ \`\`\`
12508
+ `);
12509
+ }
12510
+ applyToAgentModelRequirements(requirements, content) {
12511
+ var _a;
12512
+ const trimmedContent = content.trim();
12513
+ if (!trimmedContent) {
12514
+ return requirements;
12515
+ }
12516
+ // Get existing dictionary entries from metadata
12517
+ const existingDictionary = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.DICTIONARY) || '';
12518
+ // Merge the new dictionary entry with existing entries
12519
+ const mergedDictionary = existingDictionary ? `${existingDictionary}\n${trimmedContent}` : trimmedContent;
12520
+ // Store the merged dictionary in metadata for debugging and inspection
12521
+ const updatedMetadata = {
12522
+ ...requirements.metadata,
12523
+ DICTIONARY: mergedDictionary,
12524
+ };
12525
+ // Create the dictionary section for the system message
12526
+ // Format: "# DICTIONARY\nTerm: definition\nTerm: definition..."
12527
+ const dictionarySection = `# DICTIONARY\n${mergedDictionary}`;
12528
+ return {
12529
+ ...this.appendToSystemMessage(requirements, dictionarySection),
12530
+ metadata: updatedMetadata,
12531
+ };
12532
+ }
12533
+ }
12534
+ /**
12535
+ * Note: [💞] Ignore a discrepancy between file name and entity name
12536
+ */
12537
+
12538
+ /**
12539
+ * FORMAT commitment definition
12540
+ *
12541
+ * The FORMAT commitment defines the specific output structure and formatting
12542
+ * that the agent should use in its responses. This includes data formats,
12543
+ * response templates, and structural requirements.
12544
+ *
12545
+ * Example usage in agent source:
12546
+ *
12547
+ * ```book
12548
+ * FORMAT Always respond in JSON format with 'status' and 'data' fields
12549
+ * FORMAT Use markdown formatting for all code blocks
12550
+ * ```
12551
+ *
12552
+ * @private [🪔] Maybe export the commitments through some package
12553
+ */
12554
+ class FormatCommitmentDefinition extends BaseCommitmentDefinition {
12555
+ constructor(type = 'FORMAT') {
12556
+ super(type);
12557
+ }
12558
+ /**
12559
+ * Short one-line description of FORMAT.
12560
+ */
12561
+ get description() {
12562
+ return 'Specify output structure or formatting requirements.';
12563
+ }
12564
+ /**
12565
+ * Icon for this commitment.
12566
+ */
12567
+ get icon() {
12568
+ return '📜';
12569
+ }
12570
+ /**
12571
+ * Markdown documentation for FORMAT commitment.
12572
+ */
12573
+ get documentation() {
12574
+ return spaceTrim$1.spaceTrim(`
12575
+ # ${this.type}
12576
+
12577
+ Defines the specific output structure and formatting for responses (data formats, templates, structure).
12578
+
12579
+ ## Key aspects
12580
+
12581
+ - Both terms work identically and can be used interchangeably.
12582
+ - If they are in conflict, the last one takes precedence.
12583
+ - You can specify both data formats and presentation styles.
12584
+
12585
+ ## Examples
12586
+
12587
+ \`\`\`book
12588
+ Customer Support Bot
12589
+
12590
+ PERSONA You are a helpful customer support agent
12591
+ FORMAT Always respond in JSON format with 'status' and 'data' fields
12592
+ FORMAT Use markdown formatting for all code blocks
12593
+ \`\`\`
12594
+
12595
+ \`\`\`book
12596
+ Data Analyst
12597
+
12598
+ PERSONA You are a data analysis expert
12599
+ FORMAT Present results in structured tables
12600
+ FORMAT Include confidence scores for all predictions
12601
+ STYLE Be concise and precise in explanations
12602
+ \`\`\`
12603
+ `);
12604
+ }
12605
+ applyToAgentModelRequirements(requirements, content) {
12606
+ const trimmedContent = content.trim();
12607
+ if (!trimmedContent) {
12608
+ return requirements;
12609
+ }
12610
+ // Add format instructions to the system message
12611
+ const formatSection = `Output Format: ${trimmedContent}`;
12612
+ return this.appendToSystemMessage(requirements, formatSection, '\n\n');
12613
+ }
12614
+ }
12615
+ /**
12616
+ * Note: [💞] Ignore a discrepancy between file name and entity name
12617
+ */
12618
+
12619
+ /**
12620
+ * FROM commitment definition
12621
+ *
12622
+ * The FROM commitment tells the agent that its `agentSource` is inherited from another agent.
12623
+ *
12624
+ * Example usage in agent source:
12625
+ *
12626
+ * ```book
12627
+ * FROM https://s6.ptbk.io/benjamin-white
12628
+ * ```
12629
+ *
12630
+ * @private [🪔] Maybe export the commitments through some package
12631
+ */
12632
+ class FromCommitmentDefinition extends BaseCommitmentDefinition {
12633
+ constructor(type = 'FROM') {
12634
+ super(type);
12635
+ }
12636
+ /**
12637
+ * Short one-line description of FROM.
12638
+ */
12639
+ get description() {
12640
+ return 'Inherit agent source from another agent.';
12641
+ }
12642
+ /**
12643
+ * Icon for this commitment.
12644
+ */
12645
+ get icon() {
12646
+ return '🧬';
12647
+ }
12648
+ /**
12649
+ * Markdown documentation for FROM commitment.
12650
+ */
12651
+ get documentation() {
12652
+ return spaceTrim$1.spaceTrim(`
12653
+ # ${this.type}
12654
+
12655
+ Inherits agent source from another agent.
12656
+
12657
+ ## Examples
12658
+
12659
+ \`\`\`book
12660
+ My AI Agent
12661
+
12662
+ FROM https://s6.ptbk.io/benjamin-white
12663
+ RULE Speak only in English.
12664
+ \`\`\`
12665
+ `);
12666
+ }
12667
+ applyToAgentModelRequirements(requirements, content) {
12668
+ const trimmedContent = content.trim();
12669
+ if (!trimmedContent) {
12670
+ return {
12671
+ ...requirements,
12672
+ parentAgentUrl: undefined,
12673
+ };
12674
+ }
12675
+ if (trimmedContent.toUpperCase() === 'VOID' ||
12676
+ trimmedContent.toUpperCase() === 'NULL' ||
12677
+ trimmedContent.toUpperCase() === 'NONE' ||
12678
+ trimmedContent.toUpperCase() === 'NIL') {
12679
+ return {
12680
+ ...requirements,
12681
+ parentAgentUrl: null,
12682
+ };
12683
+ }
12684
+ if (!isValidAgentUrl(trimmedContent)) {
12685
+ throw new Error(spaceTrim$1.spaceTrim((block) => `
12686
+ Invalid agent URL in FROM commitment: "${trimmedContent}"
12687
+
12688
+ \`\`\`book
12689
+ ${block(content)}
12690
+ \`\`\`
12691
+
12692
+
12693
+ `));
12694
+ }
12695
+ const parentAgentUrl = trimmedContent;
12696
+ return {
12697
+ ...requirements,
12698
+ parentAgentUrl,
12699
+ };
12700
+ }
12701
+ }
12702
+ /**
12703
+ * Note: [💞] Ignore a discrepancy between file name and entity name
12704
+ */
12705
+
12706
+ /**
12707
+ * GOAL commitment definition
12708
+ *
12709
+ * The GOAL commitment defines the main goal which should be achieved by the AI assistant.
12710
+ * There can be multiple goals. Later goals are more important than earlier goals.
12711
+ *
12712
+ * Example usage in agent source:
12713
+ *
12714
+ * ```book
12715
+ * GOAL Help users understand complex technical concepts
12716
+ * GOAL Provide accurate and up-to-date information
12717
+ * GOAL Always prioritize user safety and ethical guidelines
12718
+ * ```
12719
+ *
12720
+ * @private [🪔] Maybe export the commitments through some package
12721
+ */
12722
+ class GoalCommitmentDefinition extends BaseCommitmentDefinition {
12723
+ constructor(type = 'GOAL') {
12724
+ super(type);
12725
+ }
12726
+ /**
12727
+ * Short one-line description of GOAL.
12728
+ */
12729
+ get description() {
12730
+ return 'Define main **goals** the AI assistant should achieve, with later goals having higher priority.';
12731
+ }
12732
+ /**
12733
+ * Icon for this commitment.
12734
+ */
12735
+ get icon() {
12736
+ return '🎯';
12737
+ }
12738
+ /**
12739
+ * Markdown documentation for GOAL commitment.
12740
+ */
12741
+ get documentation() {
12742
+ return spaceTrim$1.spaceTrim(`
12743
+ # ${this.type}
12744
+
12745
+ 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.
12746
+
12747
+ ## Key aspects
12748
+
12749
+ - Both terms work identically and can be used interchangeably.
12750
+ - Later goals have higher priority and can override earlier goals.
12751
+ - Goals provide clear direction and purpose for the agent's responses.
12752
+ - Goals influence decision-making and response prioritization.
12753
+
12754
+ ## Priority system
12755
+
12756
+ When multiple goals are defined, they are processed in order, with later goals taking precedence over earlier ones when there are conflicts.
12757
+
12758
+ ## Examples
12759
+
12760
+ \`\`\`book
12761
+ Customer Support Agent
12762
+
12763
+ PERSONA You are a helpful customer support representative
12764
+ GOAL Resolve customer issues quickly and efficiently
12765
+ GOAL Maintain high customer satisfaction scores
12766
+ GOAL Always follow company policies and procedures
12767
+ RULE Be polite and professional at all times
12768
+ \`\`\`
12769
+
12770
+ \`\`\`book
12771
+ Educational Assistant
12772
+
12773
+ PERSONA You are an educational assistant specializing in mathematics
12774
+ GOAL Help students understand mathematical concepts clearly
12775
+ GOAL Encourage critical thinking and problem-solving skills
12776
+ GOAL Ensure all explanations are age-appropriate and accessible
12777
+ STYLE Use simple language and provide step-by-step explanations
12778
+ \`\`\`
12779
+
12780
+ \`\`\`book
12781
+ Safety-First Assistant
12782
+
12783
+ PERSONA You are a general-purpose AI assistant
12784
+ GOAL Be helpful and informative in all interactions
12785
+ GOAL Provide accurate and reliable information
12786
+ GOAL Always prioritize user safety and ethical guidelines
12787
+ RULE Never provide harmful or dangerous advice
12788
+ \`\`\`
12789
+ `);
12790
+ }
12791
+ applyToAgentModelRequirements(requirements, content) {
12792
+ const trimmedContent = content.trim();
12793
+ if (!trimmedContent) {
12794
+ return requirements;
12795
+ }
12796
+ // Create goal section for system message
12797
+ const goalSection = `Goal: ${trimmedContent}`;
12798
+ // Goals are important directives, so we add them prominently to the system message
12799
+ return this.appendToSystemMessage(requirements, goalSection, '\n\n');
12800
+ }
12801
+ }
12802
+ /**
12803
+ * Note: [💞] Ignore a discrepancy between file name and entity name
12804
+ */
12805
+
12806
+ /**
12807
+ * IMPORT commitment definition
12808
+ *
12809
+ * The IMPORT commitment tells the agent to import content from another agent at the current location.
12810
+ *
12811
+ * Example usage in agent source:
12812
+ *
12813
+ * ```book
12814
+ * IMPORT https://s6.ptbk.io/benjamin-white
12815
+ * ```
12816
+ *
12817
+ * @private [🪔] Maybe export the commitments through some package
12818
+ */
12819
+ class ImportCommitmentDefinition extends BaseCommitmentDefinition {
12820
+ constructor(type = 'IMPORT') {
12821
+ super(type);
12822
+ }
12823
+ /**
12824
+ * Short one-line description of IMPORT.
12825
+ */
12826
+ get description() {
12827
+ return 'Import content from another agent or a generic text file.';
12828
+ }
12829
+ /**
12830
+ * Icon for this commitment.
12831
+ */
12832
+ get icon() {
12833
+ return '📥';
12834
+ }
12835
+ /**
12836
+ * Markdown documentation for IMPORT commitment.
12837
+ */
12838
+ get documentation() {
12839
+ return spaceTrim$1.spaceTrim(`
12840
+ # ${this.type}
12841
+
12842
+ Imports content from another agent or a generic text file at the location of the commitment.
12843
+
12844
+ ## Examples
12845
+
12846
+ \`\`\`book
12847
+ My AI Agent
12848
+
12849
+ IMPORT https://s6.ptbk.io/benjamin-white
12850
+ IMPORT https://example.com/some-text-file.txt
12851
+ IMPORT ./path/to/local-file.json
12852
+ RULE Speak only in English.
12853
+ \`\`\`
12854
+ `);
12855
+ }
12856
+ applyToAgentModelRequirements(requirements, content) {
12857
+ const trimmedContent = content.trim();
12858
+ if (!trimmedContent) {
12859
+ return requirements;
12860
+ }
12861
+ if (isValidAgentUrl(trimmedContent)) {
12862
+ const importedAgentUrl = trimmedContent;
12863
+ return {
12864
+ ...requirements,
12865
+ importedAgentUrls: [...(requirements.importedAgentUrls || []), importedAgentUrl],
12866
+ };
12867
+ }
12868
+ if (isValidUrl(trimmedContent) || isValidFilePath(trimmedContent)) {
12869
+ return {
12870
+ ...requirements,
12871
+ importedFileUrls: [...(requirements.importedFileUrls || []), trimmedContent],
12872
+ };
12873
+ }
12874
+ throw new Error(spaceTrim$1.spaceTrim((block) => `
12875
+ Invalid agent URL or file path in IMPORT commitment: "${trimmedContent}"
12876
+
12877
+ \`\`\`book
12878
+ ${block(content)}
12879
+ \`\`\`
12880
+ `));
12881
+ }
12882
+ }
12883
+ /**
12884
+ * Note: [💞] Ignore a discrepancy between file name and entity name
12885
+ */
12886
+
12887
+ /**
12888
+ * KNOWLEDGE commitment definition
12889
+ *
12890
+ * The KNOWLEDGE commitment adds specific knowledge, facts, or context to the agent
12891
+ * using RAG (Retrieval-Augmented Generation) approach for external sources.
12892
+ *
12893
+ * Supports both direct text knowledge and external sources like PDFs.
12894
+ *
12895
+ * Example usage in agent source:
12896
+ *
12897
+ * ```book
12898
+ * KNOWLEDGE The company was founded in 2020 and specializes in AI-powered solutions
12899
+ * KNOWLEDGE https://example.com/company-handbook.pdf
12900
+ * KNOWLEDGE https://example.com/product-documentation.pdf
12901
+ * ```
12902
+ *
12903
+ * @private [🪔] Maybe export the commitments through some package
12904
+ */
12905
+ class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
12906
+ constructor() {
12907
+ super('KNOWLEDGE');
12908
+ }
12909
+ /**
12910
+ * Short one-line description of KNOWLEDGE.
12911
+ */
12912
+ get description() {
12913
+ return 'Add domain **knowledge** via direct text or external sources (RAG).';
12914
+ }
12915
+ /**
12916
+ * Icon for this commitment.
12917
+ */
12918
+ get icon() {
12919
+ return '🧠';
12920
+ }
12921
+ /**
12922
+ * Markdown documentation for KNOWLEDGE commitment.
12923
+ */
12924
+ get documentation() {
12925
+ return spaceTrim$1.spaceTrim(`
12926
+ # ${this.type}
12927
+
12928
+ Adds specific knowledge, facts, or context to the agent using a RAG (Retrieval-Augmented Generation) approach for external sources.
12929
+
12930
+ ## Key aspects
12931
+
12932
+ - Both terms work identically and can be used interchangeably.
12933
+ - Supports both direct text knowledge and external URLs.
12934
+ - External sources (PDFs, websites) are processed via RAG for context retrieval.
12935
+
12936
+ ## Supported formats
12937
+
12938
+ - Direct text: Immediate knowledge incorporated into agent
12939
+ - URLs: External documents processed for contextual retrieval
12940
+ - Supported file types: PDF, text, markdown, HTML
12941
+
12942
+ ## Examples
12943
+
12944
+ \`\`\`book
12945
+ Customer Support Bot
12946
+
12947
+ PERSONA You are a helpful customer support agent for TechCorp
12948
+ KNOWLEDGE TechCorp was founded in 2020 and specializes in AI-powered solutions
12949
+ KNOWLEDGE https://example.com/company-handbook.pdf
12950
+ KNOWLEDGE https://example.com/product-documentation.pdf
12951
+ RULE Always be polite and professional
12952
+ \`\`\`
12953
+
12954
+ \`\`\`book
12955
+ Research Assistant
12956
+
12957
+ PERSONA You are a knowledgeable research assistant
12958
+ KNOWLEDGE Academic research requires careful citation and verification
12959
+ KNOWLEDGE https://example.com/research-guidelines.pdf
12960
+ ACTION Can help with literature reviews and data analysis
12961
+ STYLE Present information in clear, academic format
12962
+ \`\`\`
12963
+ `);
12964
+ }
12965
+ applyToAgentModelRequirements(requirements, content) {
12966
+ const trimmedContent = content.trim();
12967
+ if (!trimmedContent) {
12968
+ return requirements;
12969
+ }
12970
+ // Check if content is a URL (external knowledge source)
12971
+ if (isValidUrl(trimmedContent)) {
12972
+ // Store the URL for later async processing
12973
+ const updatedRequirements = {
12974
+ ...requirements,
12975
+ knowledgeSources: [
12976
+ ...(requirements.knowledgeSources || []),
12977
+ trimmedContent,
12978
+ ],
12979
+ };
12980
+ // Add placeholder information about knowledge sources to system message
12981
+ const knowledgeInfo = `Knowledge Source URL: ${trimmedContent} (will be processed for retrieval during chat)`;
12982
+ return this.appendToSystemMessage(updatedRequirements, knowledgeInfo, '\n\n');
12983
+ }
12984
+ else {
12985
+ // Direct text knowledge - add to system message
12986
+ const knowledgeSection = `Knowledge: ${trimmedContent}`;
12987
+ return this.appendToSystemMessage(requirements, knowledgeSection, '\n\n');
12988
+ }
12989
+ }
12990
+ }
12991
+ /**
12992
+ * Note: [💞] Ignore a discrepancy between file name and entity name
12993
+ */
12994
+
12995
+ /**
12996
+ * LANGUAGE commitment definition
12997
+ *
12998
+ * The LANGUAGE/LANGUAGES commitment specifies the language(s) the agent should use in its responses.
12999
+ *
13000
+ * Example usage in agent source:
13001
+ *
13002
+ * ```book
13003
+ * LANGUAGE English
13004
+ * LANGUAGE French, English and Czech
13005
+ * ```
13006
+ *
13007
+ * @private [🪔] Maybe export the commitments through some package
13008
+ */
13009
+ class LanguageCommitmentDefinition extends BaseCommitmentDefinition {
13010
+ constructor(type = 'LANGUAGE') {
13011
+ super(type);
13012
+ }
13013
+ /**
13014
+ * Short one-line description of LANGUAGE/LANGUAGES.
13015
+ */
13016
+ get description() {
13017
+ return 'Specifies the language(s) the agent should use.';
13018
+ }
13019
+ /**
13020
+ * Icon for this commitment.
13021
+ */
13022
+ get icon() {
13023
+ return '🌐';
13024
+ }
13025
+ /**
13026
+ * Markdown documentation for LANGUAGE/LANGUAGES commitment.
13027
+ */
13028
+ get documentation() {
13029
+ return spaceTrim$1.spaceTrim(`
13030
+ # ${this.type}
13031
+
13032
+ Specifies the language(s) the agent should use in its responses.
13033
+ This is a specialized variation of the RULE commitment focused on language constraints.
13034
+
13035
+ ## Examples
13036
+
13037
+ \`\`\`book
13038
+ Paul Smith & Associés
13039
+
13040
+ PERSONA You are a company lawyer.
13041
+ LANGUAGE French, English and Czech
13042
+ \`\`\`
13043
+
13044
+ \`\`\`book
13045
+ Customer Support
13046
+
13047
+ PERSONA You are a customer support agent.
13048
+ LANGUAGE English
13049
+ \`\`\`
13050
+ `);
13051
+ }
13052
+ applyToAgentModelRequirements(requirements, content) {
13053
+ const trimmedContent = content.trim();
13054
+ if (!trimmedContent) {
13055
+ return requirements;
13056
+ }
13057
+ // Add language rule to the system message
13058
+ const languageSection = `Language: ${trimmedContent}`;
13059
+ return this.appendToSystemMessage(requirements, languageSection, '\n\n');
13060
+ }
13061
+ }
13062
+ /**
13063
+ * Note: [💞] Ignore a discrepancy between file name and entity name
13064
+ */
13065
+
13066
+ /**
13067
+ * MEMORY commitment definition
13068
+ *
13069
+ * The MEMORY commitment is similar to KNOWLEDGE but has a focus on remembering past
13070
+ * interactions and user preferences. It helps the agent maintain context about the
13071
+ * user's history, preferences, and previous conversations.
13072
+ *
13073
+ * Example usage in agent source:
13074
+ *
13075
+ * ```book
13076
+ * MEMORY User prefers detailed technical explanations
13077
+ * MEMORY Previously worked on React projects
13078
+ * MEMORY Timezone: UTC-5 (Eastern Time)
13079
+ * ```
13080
+ *
13081
+ * @private [🪔] Maybe export the commitments through some package
13082
+ */
13083
+ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
13084
+ constructor(type = 'MEMORY') {
13085
+ super(type);
13086
+ }
13087
+ /**
13088
+ * Short one-line description of MEMORY.
13089
+ */
13090
+ get description() {
13091
+ return 'Remember past interactions and user **preferences** for personalized responses.';
13092
+ }
13093
+ /**
13094
+ * Icon for this commitment.
13095
+ */
13096
+ get icon() {
13097
+ return '🧠';
13098
+ }
13099
+ /**
13100
+ * Markdown documentation for MEMORY commitment.
13101
+ */
13102
+ get documentation() {
13103
+ return spaceTrim$1.spaceTrim(`
13104
+ # ${this.type}
13105
+
13106
+ 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.
13107
+
13108
+ ## Key aspects
13109
+
13110
+ - Both terms work identically and can be used interchangeably.
13111
+ - Focuses on user-specific information and interaction history.
13112
+ - Helps personalize responses based on past interactions.
13113
+ - Maintains continuity across conversations.
13114
+
13115
+ ## Differences from KNOWLEDGE
13116
+
13117
+ - \`KNOWLEDGE\` is for domain expertise and factual information
13118
+ - \`MEMORY\` is for user-specific context and preferences
13119
+ - \`MEMORY\` creates more personalized interactions
13120
+ - \`MEMORY\` often includes temporal or preference-based information
13121
+
13122
+ ## Examples
13123
+
13124
+ \`\`\`book
13125
+ Personal Assistant
13126
+
13127
+ PERSONA You are a personal productivity assistant
13128
+ MEMORY User is a software developer working in JavaScript/React
13129
+ MEMORY User prefers morning work sessions and afternoon meetings
13130
+ MEMORY Previously helped with project planning for mobile apps
13131
+ MEMORY User timezone: UTC-8 (Pacific Time)
13132
+ GOAL Help optimize daily productivity and workflow
13133
+ \`\`\`
13134
+
13135
+ \`\`\`book
13136
+ Learning Companion
13137
+
13138
+ PERSONA You are an educational companion for programming students
13139
+ MEMORY Student is learning Python as their first programming language
13140
+ MEMORY Previous topics covered: variables, loops, functions
13141
+ MEMORY Student learns best with practical examples and exercises
13142
+ MEMORY Last session: working on list comprehensions
13143
+ GOAL Provide progressive learning experiences tailored to student's pace
13144
+ \`\`\`
13145
+
13146
+ \`\`\`book
13147
+ Customer Support Agent
13148
+
13149
+ PERSONA You are a customer support representative
13150
+ MEMORY Customer has premium subscription since 2023
13151
+ MEMORY Previous issue: billing question resolved last month
13152
+ MEMORY Customer prefers email communication over phone calls
13153
+ MEMORY Account shows frequent use of advanced features
13154
+ GOAL Provide personalized support based on customer history
13155
+ \`\`\`
13156
+ `);
13157
+ }
13158
+ applyToAgentModelRequirements(requirements, content) {
13159
+ const trimmedContent = content.trim();
13160
+ if (!trimmedContent) {
13161
+ return requirements;
13162
+ }
13163
+ // Create memory section for system message
13164
+ const memorySection = `Memory: ${trimmedContent}`;
13165
+ // Memory information is contextual and should be included in the system message
13166
+ return this.appendToSystemMessage(requirements, memorySection, '\n\n');
13167
+ }
13168
+ }
13169
+ /**
13170
+ * Note: [💞] Ignore a discrepancy between file name and entity name
13171
+ */
13172
+
13173
+ /**
13174
+ * AGENT MESSAGE commitment definition
13175
+ *
13176
+ * The AGENT MESSAGE commitment defines a message from the agent in the conversation history.
13177
+ * It is used to pre-fill the chat with a conversation history or to provide few-shot examples.
13178
+ *
13179
+ * Example usage in agent source:
13180
+ *
13181
+ * ```book
13182
+ * AGENT MESSAGE What seems to be the issue?
13183
+ * ```
13184
+ *
13185
+ * @private [🪔] Maybe export the commitments through some package
13186
+ */
13187
+ class AgentMessageCommitmentDefinition extends BaseCommitmentDefinition {
13188
+ constructor() {
13189
+ super('AGENT MESSAGE');
13190
+ }
13191
+ /**
13192
+ * Short one-line description of AGENT MESSAGE.
13193
+ */
13194
+ get description() {
13195
+ return 'Defines a **message from the agent** in the conversation history.';
13196
+ }
13197
+ /**
13198
+ * Icon for this commitment.
13199
+ */
13200
+ get icon() {
13201
+ return '🤖';
13202
+ }
13203
+ /**
13204
+ * Markdown documentation for AGENT MESSAGE commitment.
13205
+ */
13206
+ get documentation() {
13207
+ return spaceTrim$1.spaceTrim(`
13208
+ # ${this.type}
13209
+
13210
+ 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.
13211
+
13212
+ ## Key aspects
13213
+
13214
+ - Represents a message sent by the agent.
13215
+ - Used for setting up conversation context.
13216
+ - Can be used in conjunction with USER MESSAGE.
13217
+
13218
+ ## Examples
13219
+
13220
+ \`\`\`book
13221
+ Conversation History
13222
+
13223
+ USER MESSAGE Hello, I have a problem.
13224
+ AGENT MESSAGE What seems to be the issue?
13225
+ USER MESSAGE My computer is not starting.
13226
+ \`\`\`
13227
+ `);
13228
+ }
13229
+ applyToAgentModelRequirements(requirements, content) {
13230
+ // AGENT MESSAGE is for UI display purposes / conversation history construction
13231
+ // and typically doesn't need to be added to the system prompt or model requirements directly.
13232
+ // It is extracted separately for the chat interface.
13233
+ var _a;
13234
+ const pendingUserMessage = (_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.pendingUserMessage;
13235
+ if (pendingUserMessage) {
13236
+ const newSample = { question: pendingUserMessage, answer: content };
13237
+ const newSamples = [...(requirements.samples || []), newSample];
13238
+ const newMetadata = { ...requirements.metadata };
13239
+ delete newMetadata.pendingUserMessage;
13240
+ return {
13241
+ ...requirements,
13242
+ samples: newSamples,
13243
+ metadata: newMetadata,
13244
+ };
13245
+ }
13246
+ return requirements;
13247
+ }
13248
+ }
13249
+
13250
+ /**
13251
+ * INITIAL MESSAGE commitment definition
13252
+ *
13253
+ * The INITIAL MESSAGE commitment defines the first message that the user sees when opening the chat.
13254
+ * It is used to greet the user and set the tone of the conversation.
13255
+ *
13256
+ * Example usage in agent source:
13257
+ *
13258
+ * ```book
13259
+ * INITIAL MESSAGE Hello! I am ready to help you with your tasks.
13260
+ * ```
13261
+ *
13262
+ * @private [🪔] Maybe export the commitments through some package
13263
+ */
13264
+ class InitialMessageCommitmentDefinition extends BaseCommitmentDefinition {
13265
+ constructor() {
13266
+ super('INITIAL MESSAGE');
13267
+ }
13268
+ /**
13269
+ * Short one-line description of INITIAL MESSAGE.
13270
+ */
13271
+ get description() {
13272
+ return 'Defines the **initial message** shown to the user when the chat starts.';
13273
+ }
13274
+ /**
13275
+ * Icon for this commitment.
13276
+ */
13277
+ get icon() {
13278
+ return '👋';
13279
+ }
13280
+ /**
13281
+ * Markdown documentation for INITIAL MESSAGE commitment.
13282
+ */
13283
+ get documentation() {
13284
+ return spaceTrim$1.spaceTrim(`
13285
+ # ${this.type}
13286
+
13287
+ 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).
13288
+
13289
+ ## Key aspects
13290
+
13291
+ - Used to greet the user.
13292
+ - Sets the tone of the conversation.
13293
+ - Displayed immediately when the chat interface loads.
13294
+
13295
+ ## Examples
13296
+
13297
+ \`\`\`book
13298
+ Support Agent
13299
+
13300
+ PERSONA You are a helpful support agent.
13301
+ INITIAL MESSAGE Hi there! How can I assist you today?
13302
+ \`\`\`
13303
+ `);
13304
+ }
13305
+ applyToAgentModelRequirements(requirements, content) {
13306
+ // INITIAL MESSAGE is for UI display purposes and for conversation history construction.
13307
+ const newSample = { question: null, answer: content };
13308
+ const newSamples = [...(requirements.samples || []), newSample];
13309
+ return {
13310
+ ...requirements,
13311
+ samples: newSamples,
13312
+ };
13313
+ }
13314
+ }
13315
+
13316
+ /**
13317
+ * MESSAGE commitment definition
13318
+ *
13319
+ * The MESSAGE commitment contains 1:1 text of the message which AI assistant already
13320
+ * sent during the conversation. Later messages are later in the conversation.
13321
+ * It is similar to EXAMPLE but it is not example, it is the real message which
13322
+ * AI assistant already sent.
13323
+ *
13324
+ * Example usage in agent source:
13325
+ *
13326
+ * ```book
13327
+ * MESSAGE Hello! How can I help you today?
13328
+ * MESSAGE I understand you're looking for information about our services.
13329
+ * MESSAGE Based on your requirements, I'd recommend our premium package.
13330
+ * ```
13331
+ *
13332
+ * @private [🪔] Maybe export the commitments through some package
13333
+ */
13334
+ class MessageCommitmentDefinition extends BaseCommitmentDefinition {
13335
+ constructor(type = 'MESSAGE') {
13336
+ super(type);
13337
+ }
13338
+ /**
13339
+ * Short one-line description of MESSAGE.
13340
+ */
13341
+ get description() {
13342
+ return 'Include actual **messages** the AI assistant has sent during conversation history.';
13343
+ }
13344
+ /**
13345
+ * Icon for this commitment.
13346
+ */
13347
+ get icon() {
13348
+ return '💬';
13349
+ }
13350
+ /**
13351
+ * Markdown documentation for MESSAGE commitment.
13352
+ */
13353
+ get documentation() {
13354
+ return spaceTrim$1.spaceTrim(`
13355
+ # ${this.type}
13356
+
13357
+ 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.
13358
+
13359
+ ## Key aspects
13360
+
13361
+ - Multiple \`MESSAGE\` and \`MESSAGES\` commitments represent the conversation timeline.
13362
+ - Both terms work identically and can be used interchangeably.
13363
+ - Later messages are later in the conversation chronologically.
13364
+ - Contains actual historical messages, not examples or templates.
13365
+ - Helps maintain conversation continuity and context.
13366
+
13367
+ ## Differences from EXAMPLE
13368
+
13369
+ - \`EXAMPLE\` shows hypothetical or template responses
13370
+ - \`MESSAGE\`/\`MESSAGES\` contains actual historical conversation content
13371
+ - \`MESSAGE\`/\`MESSAGES\` preserves the exact conversation flow
13372
+ - \`MESSAGE\`/\`MESSAGES\` helps with context awareness and consistency
13373
+
13374
+ ## Use cases
13375
+
13376
+ - Maintaining conversation history context
13377
+ - Ensuring consistent tone and style across messages
13378
+ - Referencing previous responses in ongoing conversations
13379
+ - Building upon previously established context
13380
+
13381
+ ## Examples
13382
+
13383
+ \`\`\`book
13384
+ Customer Support Continuation
13385
+
13386
+ PERSONA You are a helpful customer support agent
13387
+ MESSAGE Hello! How can I help you today?
13388
+ MESSAGE I understand you're experiencing issues with your account login.
13389
+ MESSAGE I've sent you a password reset link to your email address.
13390
+ MESSAGE Is there anything else I can help you with regarding your account?
13391
+ GOAL Continue providing consistent support based on conversation history
13392
+ \`\`\`
13393
+
13394
+ \`\`\`book
13395
+ Technical Discussion
13396
+
13397
+ PERSONA You are a software development mentor
13398
+ MESSAGE Let's start by reviewing the React component structure you shared.
13399
+ MESSAGE I notice you're using class components - have you considered hooks?
13400
+ MESSAGE Here's how you could refactor that using the useState hook.
13401
+ MESSAGE Great question about performance! Let me explain React's rendering cycle.
13402
+ KNOWLEDGE React hooks were introduced in version 16.8
13403
+ \`\`\`
13404
+
13405
+ \`\`\`book
13406
+ Educational Session
13407
+
13408
+ PERSONA You are a mathematics tutor
13409
+ MESSAGE Today we'll work on solving quadratic equations.
13410
+ MESSAGE Let's start with the basic form: ax² + bx + c = 0
13411
+ MESSAGE Remember, we can use the quadratic formula or factoring.
13412
+ MESSAGE You did great with that first problem! Let's try a more complex one.
13413
+ GOAL Build upon previous explanations for deeper understanding
13414
+ \`\`\`
13415
+ `);
13416
+ }
13417
+ applyToAgentModelRequirements(requirements, content) {
13418
+ const trimmedContent = content.trim();
13419
+ if (!trimmedContent) {
13420
+ return requirements;
13421
+ }
13422
+ // Create message section for system message
13423
+ const messageSection = `Previous Message: ${trimmedContent}`;
13424
+ // Messages represent conversation history and should be included for context
13425
+ return this.appendToSystemMessage(requirements, messageSection, '\n\n');
13426
+ }
13427
+ }
13428
+ /**
13429
+ * Note: [💞] Ignore a discrepancy between file name and entity name
13430
+ */
13431
+
13432
+ /**
13433
+ * USER MESSAGE commitment definition
13434
+ *
13435
+ * The USER MESSAGE commitment defines a message from the user in the conversation history.
13436
+ * It is used to pre-fill the chat with a conversation history or to provide few-shot examples.
13437
+ *
13438
+ * Example usage in agent source:
13439
+ *
13440
+ * ```book
13441
+ * USER MESSAGE Hello, I have a problem.
13442
+ * ```
13443
+ *
13444
+ * @private [🪔] Maybe export the commitments through some package
13445
+ */
13446
+ class UserMessageCommitmentDefinition extends BaseCommitmentDefinition {
13447
+ constructor() {
13448
+ super('USER MESSAGE');
13449
+ }
13450
+ /**
13451
+ * Short one-line description of USER MESSAGE.
13452
+ */
13453
+ get description() {
13454
+ return 'Defines a **message from the user** in the conversation history.';
13455
+ }
13456
+ /**
13457
+ * Icon for this commitment.
13458
+ */
13459
+ get icon() {
13460
+ return '🧑';
13461
+ }
13462
+ /**
13463
+ * Markdown documentation for USER MESSAGE commitment.
13464
+ */
13465
+ get documentation() {
13466
+ return spaceTrim$1.spaceTrim(`
13467
+ # ${this.type}
13468
+
13469
+ 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.
13470
+
13471
+ ## Key aspects
13472
+
13473
+ - Represents a message sent by the user.
13474
+ - Used for setting up conversation context.
13475
+ - Can be used in conjunction with AGENT MESSAGE.
13476
+
13477
+ ## Examples
13478
+
13479
+ \`\`\`book
13480
+ Conversation History
13481
+
13482
+ USER MESSAGE Hello, I have a problem.
13483
+ AGENT MESSAGE What seems to be the issue?
13484
+ USER MESSAGE My computer is not starting.
13485
+ \`\`\`
13486
+ `);
13487
+ }
13488
+ applyToAgentModelRequirements(requirements, content) {
13489
+ return {
13490
+ ...requirements,
13491
+ metadata: {
13492
+ ...requirements.metadata,
13493
+ pendingUserMessage: content,
13494
+ },
13495
+ };
13496
+ }
13497
+ }
13498
+
13499
+ /**
13500
+ * META commitment definition
13501
+ *
13502
+ * The META commitment handles all meta-information about the agent such as:
13503
+ * - META IMAGE: Sets the agent's avatar/profile image URL
13504
+ * - META LINK: Provides profile/source links for the person the agent models
13505
+ * - META TITLE: Sets the agent's display title
13506
+ * - META DESCRIPTION: Sets the agent's description
13507
+ * - META [ANYTHING]: Any other meta information in uppercase format
13508
+ *
13509
+ * These commitments are special because they don't affect the system message,
13510
+ * but are handled separately in the parsing logic for profile display.
13511
+ *
13512
+ * Example usage in agent source:
13513
+ *
13514
+ * ```book
13515
+ * META IMAGE https://example.com/avatar.jpg
13516
+ * META LINK https://twitter.com/username
13517
+ * META TITLE Professional Assistant
13518
+ * META DESCRIPTION An AI assistant specialized in business tasks
13519
+ * META AUTHOR John Doe
13520
+ * META VERSION 1.0
13521
+ * ```
13522
+ *
13523
+ * @private [🪔] Maybe export the commitments through some package
13524
+ */
13525
+ class MetaCommitmentDefinition extends BaseCommitmentDefinition {
13526
+ constructor() {
13527
+ super('META');
13528
+ }
13529
+ /**
13530
+ * Short one-line description of META commitments.
13531
+ */
13532
+ get description() {
13533
+ return 'Set meta-information about the agent (IMAGE, LINK, TITLE, DESCRIPTION, etc.).';
13534
+ }
13535
+ /**
13536
+ * Icon for this commitment.
13537
+ */
13538
+ get icon() {
13539
+ return 'ℹ️';
13540
+ }
13541
+ /**
13542
+ * Markdown documentation for META commitment.
13543
+ */
13544
+ get documentation() {
13545
+ return spaceTrim$1.spaceTrim(`
13546
+ # META
13547
+
13548
+ Sets meta-information about the agent that is used for display and attribution purposes.
13549
+
13550
+ ## Supported META types
13551
+
13552
+ - **META IMAGE** - Sets the agent's avatar/profile image URL
13553
+ - **META LINK** - Provides profile/source links for the person the agent models
13554
+ - **META TITLE** - Sets the agent's display title
13555
+ - **META DESCRIPTION** - Sets the agent's description
13556
+ - **META [ANYTHING]** - Any other meta information in uppercase format
13557
+
13558
+ ## Key aspects
13559
+
13560
+ - Does not modify the agent's behavior or responses
13561
+ - Used for visual representation and attribution in user interfaces
13562
+ - Multiple META commitments of different types can be used
13563
+ - Multiple META LINK commitments can be used for different social profiles
13564
+ - If multiple META commitments of the same type are specified, the last one takes precedence (except for LINK)
13565
+
13566
+ ## Examples
13567
+
13568
+ ### Basic meta information
13569
+
13570
+ \`\`\`book
13571
+ Professional Assistant
13572
+
13573
+ META IMAGE https://example.com/professional-avatar.jpg
13574
+ META TITLE Senior Business Consultant
13575
+ META DESCRIPTION Specialized in strategic planning and project management
13576
+ META LINK https://linkedin.com/in/professional
13577
+ \`\`\`
13578
+
13579
+ ### Multiple links and custom meta
13580
+
13581
+ \`\`\`book
13582
+ Open Source Developer
13583
+
13584
+ META IMAGE /assets/dev-avatar.png
13585
+ META LINK https://github.com/developer
13586
+ META LINK https://twitter.com/devhandle
13587
+ META AUTHOR Jane Smith
13588
+ META VERSION 2.1
13589
+ META LICENSE MIT
13590
+ \`\`\`
13591
+
13592
+ ### Creative assistant
13593
+
13594
+ \`\`\`book
13595
+ Creative Helper
13596
+
13597
+ META IMAGE https://example.com/creative-bot.jpg
13598
+ META TITLE Creative Writing Assistant
13599
+ META DESCRIPTION Helps with brainstorming, storytelling, and creative projects
13600
+ META INSPIRATION Books, movies, and real-world experiences
13601
+ \`\`\`
13602
+ `);
13603
+ }
13604
+ applyToAgentModelRequirements(requirements, content) {
13605
+ // META commitments don't modify the system message or model requirements
13606
+ // They are handled separately in the parsing logic for meta information extraction
13607
+ // This method exists for consistency with the CommitmentDefinition interface
13608
+ return requirements;
13609
+ }
13610
+ /**
13611
+ * Extracts meta information from the content based on the meta type
13612
+ * This is used by the parsing logic
13613
+ */
13614
+ extractMetaValue(metaType, content) {
13615
+ const trimmedContent = content.trim();
13616
+ return trimmedContent || null;
13617
+ }
13618
+ /**
13619
+ * Validates if the provided content is a valid URL (for IMAGE and LINK types)
13620
+ */
13621
+ isValidUrl(content) {
13622
+ try {
13623
+ new URL(content.trim());
13624
+ return true;
13625
+ }
13626
+ catch (_a) {
13627
+ return false;
13628
+ }
13629
+ }
13630
+ /**
13631
+ * Checks if this is a known meta type
13632
+ */
13633
+ isKnownMetaType(metaType) {
13634
+ const knownTypes = ['IMAGE', 'LINK', 'TITLE', 'DESCRIPTION', 'AUTHOR', 'VERSION', 'LICENSE'];
13635
+ return knownTypes.includes(metaType.toUpperCase());
13636
+ }
13637
+ }
13638
+ /**
13639
+ * Note: [💞] Ignore a discrepancy between file name and entity name
13640
+ */
13641
+
13642
+ /**
13643
+ * META COLOR commitment definition
13644
+ *
13645
+ * The META COLOR commitment sets the agent's accent color.
13646
+ * This commitment is special because it doesn't affect the system message,
13647
+ * but is handled separately in the parsing logic.
13648
+ *
13649
+ * Example usage in agent source:
13650
+ *
13651
+ * ```book
13652
+ * META COLOR #ff0000
13653
+ * META COLOR #00ff00
13654
+ * ```
13655
+ *
13656
+ * You can also specify multiple colors separated by comma:
13657
+ *
13658
+ * ```book
13659
+ * META COLOR #ff0000, #00ff00, #0000ff
13660
+ * ```
13661
+ *
13662
+ * @private [🪔] Maybe export the commitments through some package
13663
+ */
13664
+ class MetaColorCommitmentDefinition extends BaseCommitmentDefinition {
13665
+ constructor() {
13666
+ super('META COLOR', ['COLOR']);
13667
+ }
13668
+ /**
13669
+ * Short one-line description of META COLOR.
13670
+ */
13671
+ get description() {
13672
+ return "Set the agent's accent color or gradient.";
13673
+ }
13674
+ /**
13675
+ * Icon for this commitment.
13676
+ */
13677
+ get icon() {
13678
+ return '🎨';
13679
+ }
13680
+ /**
13681
+ * Markdown documentation for META COLOR commitment.
13682
+ */
13683
+ get documentation() {
13684
+ return spaceTrim$1.spaceTrim(`
13685
+ # META COLOR
13686
+
13687
+ Sets the agent's accent color or gradient.
13688
+
13689
+ ## Key aspects
13690
+
13691
+ - Does not modify the agent's behavior or responses.
13692
+ - Only one \`META COLOR\` should be used per agent.
13693
+ - If multiple are specified, the last one takes precedence.
13694
+ - Used for visual representation in user interfaces.
13695
+ - Can specify multiple colors separated by comma to create a gradient.
13696
+
13697
+ ## Examples
13698
+
13699
+ \`\`\`book
13700
+ Professional Assistant
13701
+
13702
+ META COLOR #3498db
13703
+ PERSONA You are a professional business assistant
13704
+ \`\`\`
13705
+
13706
+ \`\`\`book
13707
+ Creative Helper
13708
+
13709
+ META COLOR #e74c3c
13710
+ PERSONA You are a creative and inspiring assistant
13711
+ \`\`\`
13712
+
13713
+ \`\`\`book
13714
+ Gradient Agent
13715
+
13716
+ META COLOR #ff0000, #00ff00, #0000ff
13717
+ PERSONA You are a colorful agent
13718
+ \`\`\`
13719
+ `);
13720
+ }
13721
+ applyToAgentModelRequirements(requirements, content) {
13722
+ // META COLOR doesn't modify the system message or model requirements
13723
+ // It's handled separately in the parsing logic for profile color extraction
13724
+ // This method exists for consistency with the CommitmentDefinition interface
13725
+ return requirements;
13726
+ }
13727
+ /**
13728
+ * Extracts the profile color from the content
13729
+ * This is used by the parsing logic
13730
+ */
13731
+ extractProfileColor(content) {
13732
+ const trimmedContent = content.trim();
13733
+ return trimmedContent || null;
13734
+ }
13735
+ }
13736
+ /**
13737
+ * Note: [💞] Ignore a discrepancy between file name and entity name
13738
+ */
13739
+
13740
+ /**
13741
+ * META FONT commitment definition
13742
+ *
13743
+ * The META FONT commitment sets the agent's font.
13744
+ * This commitment is special because it doesn't affect the system message,
13745
+ * but is handled separately in the parsing logic.
13746
+ *
13747
+ * Example usage in agent source:
13748
+ *
13749
+ * ```book
13750
+ * META FONT Poppins, Arial, sans-serif
13751
+ * META FONT Roboto
13752
+ * ```
13753
+ *
13754
+ * @private [🪔] Maybe export the commitments through some package
13755
+ */
13756
+ class MetaFontCommitmentDefinition extends BaseCommitmentDefinition {
13757
+ constructor() {
13758
+ super('META FONT', ['FONT']);
13759
+ }
13760
+ /**
13761
+ * Short one-line description of META FONT.
13762
+ */
13763
+ get description() {
13764
+ return "Set the agent's font.";
13765
+ }
13766
+ /**
13767
+ * Icon for this commitment.
13768
+ */
13769
+ get icon() {
13770
+ return '🔤';
13771
+ }
13772
+ /**
13773
+ * Markdown documentation for META FONT commitment.
13774
+ */
13775
+ get documentation() {
13776
+ return spaceTrim$1.spaceTrim(`
13777
+ # META FONT
13778
+
13779
+ Sets the agent's font.
13780
+
13781
+ ## Key aspects
13782
+
13783
+ - Does not modify the agent's behavior or responses.
13784
+ - Only one \`META FONT\` should be used per agent.
13785
+ - If multiple are specified, the last one takes precedence.
13786
+ - Used for visual representation in user interfaces.
13787
+ - Supports Google Fonts.
13788
+
13789
+ ## Examples
13790
+
13791
+ \`\`\`book
13792
+ Modern Assistant
13793
+
13794
+ META FONT Poppins, Arial, sans-serif
13795
+ PERSONA You are a modern assistant
13796
+ \`\`\`
13797
+
13798
+ \`\`\`book
13799
+ Classic Helper
13800
+
13801
+ META FONT Times New Roman
13802
+ PERSONA You are a classic helper
13803
+ \`\`\`
13804
+ `);
13805
+ }
13806
+ applyToAgentModelRequirements(requirements, content) {
13807
+ // META FONT doesn't modify the system message or model requirements
13808
+ // It's handled separately in the parsing logic
13809
+ // This method exists for consistency with the CommitmentDefinition interface
13810
+ return requirements;
13811
+ }
13812
+ /**
13813
+ * Extracts the font from the content
13814
+ * This is used by the parsing logic
13815
+ */
13816
+ extractProfileFont(content) {
13817
+ const trimmedContent = content.trim();
13818
+ return trimmedContent || null;
13819
+ }
13820
+ }
13821
+ /**
13822
+ * Note: [💞] Ignore a discrepancy between file name and entity name
13823
+ */
13824
+
13825
+ /**
13826
+ * META IMAGE commitment definition
13827
+ *
13828
+ * The META IMAGE commitment sets the agent's avatar/profile image URL.
13829
+ * This commitment is special because it doesn't affect the system message,
13830
+ * but is handled separately in the parsing logic.
13831
+ *
13832
+ * Example usage in agent source:
13833
+ *
13834
+ * ```book
13835
+ * META IMAGE https://example.com/avatar.jpg
13836
+ * META IMAGE /assets/agent-avatar.png
13837
+ * ```
13838
+ *
13839
+ * @private [🪔] Maybe export the commitments through some package
13840
+ */
13841
+ class MetaImageCommitmentDefinition extends BaseCommitmentDefinition {
13842
+ constructor() {
13843
+ super('META IMAGE', ['IMAGE']);
13844
+ }
13845
+ /**
13846
+ * Short one-line description of META IMAGE.
13847
+ */
13848
+ get description() {
13849
+ return "Set the agent's profile image URL.";
13850
+ }
13851
+ /**
13852
+ * Icon for this commitment.
13853
+ */
13854
+ get icon() {
13855
+ return '🖼️';
13856
+ }
13857
+ /**
13858
+ * Markdown documentation for META IMAGE commitment.
13859
+ */
13860
+ get documentation() {
13861
+ return spaceTrim$1.spaceTrim(`
13862
+ # META IMAGE
13863
+
13864
+ Sets the agent's avatar/profile image URL.
13865
+
13866
+ ## Key aspects
13867
+
13868
+ - Does not modify the agent's behavior or responses.
13869
+ - Only one \`META IMAGE\` should be used per agent.
13870
+ - If multiple are specified, the last one takes precedence.
13871
+ - Used for visual representation in user interfaces.
13872
+
13873
+ ## Examples
13874
+
13875
+ \`\`\`book
13876
+ Professional Assistant
13877
+
13878
+ META IMAGE https://example.com/professional-avatar.jpg
13879
+ PERSONA You are a professional business assistant
13880
+ STYLE Maintain a formal and courteous tone
13881
+ \`\`\`
13882
+
13883
+ \`\`\`book
13884
+ Creative Helper
13885
+
13886
+ META IMAGE /assets/creative-bot-avatar.png
13887
+ PERSONA You are a creative and inspiring assistant
13888
+ STYLE Be enthusiastic and encouraging
13889
+ ACTION Can help with brainstorming and ideation
13890
+ \`\`\`
13891
+ `);
13892
+ }
13893
+ applyToAgentModelRequirements(requirements, content) {
13894
+ // META IMAGE doesn't modify the system message or model requirements
13895
+ // It's handled separately in the parsing logic for profile image extraction
13896
+ // This method exists for consistency with the CommitmentDefinition interface
13897
+ return requirements;
13898
+ }
13899
+ /**
13900
+ * Extracts the profile image URL from the content
13901
+ * This is used by the parsing logic
13902
+ */
13903
+ extractProfileImageUrl(content) {
13904
+ const trimmedContent = content.trim();
13905
+ return trimmedContent || null;
13906
+ }
13907
+ }
13908
+ /**
13909
+ * Note: [💞] Ignore a discrepancy between file name and entity name
13910
+ */
13911
+
13912
+ /**
13913
+ * META LINK commitment definition
13914
+ *
13915
+ * The `META LINK` commitment represents the link to the person from whom the agent is created.
13916
+ * This commitment is special because it doesn't affect the system message,
13917
+ * but is handled separately in the parsing logic for profile display.
13918
+ *
13919
+ * Example usage in agent source:
13920
+ *
13921
+ * ```
13922
+ * META LINK https://twitter.com/username
13923
+ * META LINK https://linkedin.com/in/profile
13924
+ * META LINK https://github.com/username
13925
+ * ```
13926
+ *
13927
+ * Multiple `META LINK` commitments can be used when there are multiple sources:
13928
+ *
13929
+ * ```book
13930
+ * META LINK https://twitter.com/username
13931
+ * META LINK https://linkedin.com/in/profile
13932
+ * ```
13933
+ *
13934
+ * @private [🪔] Maybe export the commitments through some package
13935
+ */
13936
+ class MetaLinkCommitmentDefinition extends BaseCommitmentDefinition {
13937
+ constructor() {
13938
+ super('META LINK');
13939
+ }
13940
+ /**
13941
+ * Short one-line description of META LINK.
13942
+ */
13943
+ get description() {
13944
+ return 'Provide profile/source links for the person the agent models.';
13945
+ }
13946
+ /**
13947
+ * Icon for this commitment.
13948
+ */
13949
+ get icon() {
13950
+ return '🔗';
13951
+ }
13952
+ /**
13953
+ * Markdown documentation for META LINK commitment.
13954
+ */
13955
+ get documentation() {
13956
+ return spaceTrim$1.spaceTrim(`
13957
+ # META LINK
13958
+
13959
+ Represents a profile or source link for the person the agent is modeled after.
13960
+
13961
+ ## Key aspects
13962
+
13963
+ - Does not modify the agent's behavior or responses.
13964
+ - Multiple \`META LINK\` commitments can be used for different social profiles.
13965
+ - Used for attribution and crediting the original person.
13966
+ - Displayed in user interfaces for transparency.
13967
+
13968
+ ## Examples
13969
+
13970
+ \`\`\`book
13971
+ Expert Consultant
13972
+
13973
+ META LINK https://twitter.com/expertname
13974
+ META LINK https://linkedin.com/in/expertprofile
13975
+ PERSONA You are Dr. Smith, a renowned expert in artificial intelligence
13976
+ KNOWLEDGE Extensive background in machine learning and neural networks
13977
+ \`\`\`
13978
+
13979
+ \`\`\`book
13980
+ Open Source Developer
13981
+
13982
+ META LINK https://github.com/developer
13983
+ META LINK https://twitter.com/devhandle
13984
+ PERSONA You are an experienced open source developer
13985
+ ACTION Can help with code reviews and architecture decisions
13986
+ STYLE Be direct and technical in explanations
13987
+ \`\`\`
13988
+ `);
13989
+ }
13990
+ applyToAgentModelRequirements(requirements, content) {
13991
+ // META LINK doesn't modify the system message or model requirements
13992
+ // It's handled separately in the parsing logic for profile link extraction
13993
+ // This method exists for consistency with the CommitmentDefinition interface
13994
+ return requirements;
13995
+ }
13996
+ /**
13997
+ * Extracts the profile link URL from the content
13998
+ * This is used by the parsing logic
13999
+ */
14000
+ extractProfileLinkUrl(content) {
14001
+ const trimmedContent = content.trim();
14002
+ return trimmedContent || null;
14003
+ }
14004
+ /**
14005
+ * Validates if the provided content is a valid URL
14006
+ */
14007
+ isValidUrl(content) {
14008
+ try {
14009
+ new URL(content.trim());
14010
+ return true;
14011
+ }
14012
+ catch (_a) {
14013
+ return false;
14014
+ }
14015
+ }
14016
+ }
14017
+ /**
14018
+ * Note: [💞] Ignore a discrepancy between file name and entity name
14019
+ */
14020
+
14021
+ /**
14022
+ * MODEL commitment definition
14023
+ *
14024
+ * The MODEL commitment specifies which AI model to use and can also set
14025
+ * model-specific parameters like temperature, topP, topK, and maxTokens.
14026
+ *
14027
+ * Supports multiple syntax variations:
14028
+ *
14029
+ * Single-line format:
14030
+ * ```book
14031
+ * MODEL gpt-4
14032
+ * MODEL claude-3-opus temperature=0.3
14033
+ * MODEL gpt-3.5-turbo temperature=0.8 topP=0.9
14034
+ * ```
14035
+ *
14036
+ * Multi-line named parameter format:
14037
+ * ```book
14038
+ * MODEL NAME gpt-4
14039
+ * MODEL TEMPERATURE 0.7
14040
+ * MODEL TOP_P 0.9
14041
+ * MODEL MAX_TOKENS 2048
14042
+ * ```
14043
+ *
14044
+ * @private [🪔] Maybe export the commitments through some package
14045
+ */
14046
+ class ModelCommitmentDefinition extends BaseCommitmentDefinition {
14047
+ constructor(type = 'MODEL') {
14048
+ super(type);
14049
+ }
14050
+ /**
14051
+ * Short one-line description of MODEL.
14052
+ */
14053
+ get description() {
14054
+ return 'Enforce AI model requirements including name and technical parameters.';
14055
+ }
14056
+ /**
14057
+ * Icon for this commitment.
14058
+ */
14059
+ get icon() {
14060
+ return '⚙️';
14061
+ }
14062
+ /**
14063
+ * Markdown documentation for MODEL commitment.
14064
+ */
14065
+ get documentation() {
14066
+ return spaceTrim$1.spaceTrim(`
14067
+ # ${this.type}
14068
+
14069
+ Enforces technical parameters for the AI model, ensuring consistent behavior across different execution environments.
14070
+
14071
+ ## Key aspects
14072
+
14073
+ - When no \`MODEL\` commitment is specified, the best model requirement is picked automatically based on the agent \`PERSONA\`, \`KNOWLEDGE\`, \`TOOLS\` and other commitments
14074
+ - Multiple \`MODEL\` commitments can be used to specify different parameters
14075
+ - Both \`MODEL\` and \`MODELS\` terms work identically and can be used interchangeably
14076
+ - Parameters control the randomness, creativity, and technical aspects of model responses
14077
+
14078
+ ## Syntax variations
14079
+
14080
+ ### Single-line format (legacy support)
14081
+ \`\`\`book
14082
+ MODEL gpt-4
14083
+ MODEL claude-3-opus temperature=0.3
14084
+ MODEL gpt-3.5-turbo temperature=0.8 topP=0.9
14085
+ \`\`\`
14086
+
14087
+ ### Multi-line named parameter format (recommended)
14088
+ \`\`\`book
14089
+ MODEL NAME gpt-4
14090
+ MODEL TEMPERATURE 0.7
14091
+ MODEL TOP_P 0.9
14092
+ MODEL MAX_TOKENS 2048
14093
+ \`\`\`
14094
+
14095
+ ## Supported parameters
14096
+
14097
+ - \`NAME\`: The specific model to use (e.g., 'gpt-4', 'claude-3-opus')
14098
+ - \`TEMPERATURE\`: Controls randomness (0.0 = deterministic, 1.0+ = creative)
14099
+ - \`TOP_P\`: Nucleus sampling parameter for controlling diversity
14100
+ - \`TOP_K\`: Top-k sampling parameter for limiting vocabulary
14101
+ - \`MAX_TOKENS\`: Maximum number of tokens the model can generate
14102
+
14103
+ ## Examples
14104
+
14105
+ ### Precise deterministic assistant
14106
+ \`\`\`book
14107
+ Precise Assistant
14108
+
14109
+ PERSONA You are a precise and accurate assistant
14110
+ MODEL NAME gpt-4
14111
+ MODEL TEMPERATURE 0.1
14112
+ MODEL MAX_TOKENS 1024
14113
+ RULE Always provide factual information
14114
+ \`\`\`
14115
+
14116
+ ### Creative writing assistant
14117
+ \`\`\`book
14118
+ Creative Writer
14119
+
14120
+ PERSONA You are a creative writing assistant
14121
+ MODEL NAME claude-3-opus
14122
+ MODEL TEMPERATURE 0.8
14123
+ MODEL TOP_P 0.9
14124
+ MODEL MAX_TOKENS 2048
14125
+ STYLE Be imaginative and expressive
14126
+ ACTION Can help with storytelling and character development
14127
+ \`\`\`
14128
+
14129
+ ### Balanced conversational agent
14130
+ \`\`\`book
14131
+ Balanced Assistant
14132
+
14133
+ PERSONA You are a helpful and balanced assistant
14134
+ MODEL NAME gpt-4
14135
+ MODEL TEMPERATURE 0.7
14136
+ MODEL TOP_P 0.95
14137
+ MODEL TOP_K 40
14138
+ MODEL MAX_TOKENS 1500
14139
+ \`\`\`
14140
+ `);
14141
+ }
14142
+ applyToAgentModelRequirements(requirements, content) {
14143
+ var _a;
14144
+ const trimmedContent = content.trim();
14145
+ if (!trimmedContent) {
14146
+ return requirements;
14147
+ }
14148
+ const parts = trimmedContent.split(/\s+/);
14149
+ const firstPart = (_a = parts[0]) === null || _a === void 0 ? void 0 : _a.toUpperCase();
14150
+ // Check if this is the new named parameter format
14151
+ if (this.isNamedParameter(firstPart)) {
14152
+ return this.parseNamedParameter(requirements, firstPart, parts.slice(1));
14153
+ }
14154
+ else {
14155
+ // Legacy single-line format: "MODEL gpt-4 temperature=0.3 topP=0.9"
14156
+ return this.parseLegacyFormat(requirements, parts);
14157
+ }
14158
+ }
14159
+ /**
14160
+ * Check if the first part is a known named parameter
14161
+ */
14162
+ isNamedParameter(part) {
14163
+ if (!part)
14164
+ return false;
14165
+ const knownParams = ['NAME', 'TEMPERATURE', 'TOP_P', 'TOP_K', 'MAX_TOKENS'];
14166
+ return knownParams.includes(part);
14167
+ }
14168
+ /**
14169
+ * Parse the new named parameter format: "MODEL TEMPERATURE 0.7"
14170
+ */
14171
+ parseNamedParameter(requirements, parameterName, valueParts) {
14172
+ const value = valueParts.join(' ').trim();
14173
+ if (!value) {
14174
+ return requirements;
14175
+ }
14176
+ const result = { ...requirements };
14177
+ switch (parameterName) {
14178
+ case 'NAME':
14179
+ result.modelName = value;
14180
+ break;
14181
+ case 'TEMPERATURE': {
14182
+ const temperature = parseFloat(value);
14183
+ if (!isNaN(temperature)) {
14184
+ result.temperature = temperature;
14185
+ }
14186
+ break;
14187
+ }
14188
+ case 'TOP_P': {
14189
+ const topP = parseFloat(value);
14190
+ if (!isNaN(topP)) {
14191
+ result.topP = topP;
14192
+ }
14193
+ break;
14194
+ }
14195
+ case 'TOP_K': {
14196
+ const topK = parseFloat(value);
14197
+ if (!isNaN(topK)) {
14198
+ result.topK = Math.round(topK);
14199
+ }
14200
+ break;
14201
+ }
14202
+ case 'MAX_TOKENS': {
14203
+ const maxTokens = parseFloat(value);
14204
+ if (!isNaN(maxTokens)) {
14205
+ result.maxTokens = Math.round(maxTokens);
14206
+ }
14207
+ break;
14208
+ }
14209
+ }
14210
+ return result;
14211
+ }
14212
+ /**
14213
+ * Parse the legacy format: "MODEL gpt-4 temperature=0.3 topP=0.9"
14214
+ */
14215
+ parseLegacyFormat(requirements, parts) {
14216
+ const modelName = parts[0];
14217
+ if (!modelName) {
14218
+ return requirements;
14219
+ }
14220
+ // Start with the model name
14221
+ const result = {
14222
+ ...requirements,
14223
+ modelName,
14224
+ };
14225
+ // Parse additional key=value parameters
14226
+ for (let i = 1; i < parts.length; i++) {
14227
+ const param = parts[i];
14228
+ if (param && param.includes('=')) {
14229
+ const [key, value] = param.split('=');
14230
+ if (key && value) {
14231
+ const numValue = parseFloat(value);
14232
+ if (!isNaN(numValue)) {
14233
+ switch (key.toLowerCase()) {
14234
+ case 'temperature':
14235
+ result.temperature = numValue;
14236
+ break;
14237
+ case 'topp':
14238
+ case 'top_p':
14239
+ result.topP = numValue;
14240
+ break;
14241
+ case 'topk':
14242
+ case 'top_k':
14243
+ result.topK = Math.round(numValue);
14244
+ break;
14245
+ case 'max_tokens':
14246
+ case 'maxTokens':
14247
+ result.maxTokens = Math.round(numValue);
14248
+ break;
14249
+ }
14250
+ }
14251
+ }
14252
+ }
14253
+ }
14254
+ return result;
14255
+ }
14256
+ }
14257
+ /**
14258
+ * Note: [💞] Ignore a discrepancy between file name and entity name
14259
+ */
14260
+
14261
+ /**
14262
+ * NOTE commitment definition
14263
+ *
14264
+ * The NOTE commitment is used to add comments to the agent source without making any changes
14265
+ * to the system message or agent model requirements. It serves as a documentation mechanism
14266
+ * for developers to add explanatory comments, reminders, or annotations directly in the agent source.
14267
+ *
14268
+ * Key features:
14269
+ * - Makes no changes to the system message
14270
+ * - Makes no changes to agent model requirements
14271
+ * - Content is preserved in metadata.NOTE for debugging and inspection
14272
+ * - Multiple NOTE commitments are aggregated together
14273
+ * - Comments (# NOTE) are removed from the final system message
14274
+ *
14275
+ * Example usage in agent source:
14276
+ *
14277
+ * ```book
14278
+ * NOTE This agent was designed for customer support scenarios
14279
+ * NOTE Remember to update the knowledge base monthly
14280
+ * NOTE Performance optimized for quick response times
14281
+ * ```
14282
+ *
14283
+ * The above notes will be stored in metadata but won't affect the agent's behavior.
14284
+ *
14285
+ * @private [🪔] Maybe export the commitments through some package
14286
+ */
14287
+ class NoteCommitmentDefinition extends BaseCommitmentDefinition {
14288
+ constructor(type = 'NOTE') {
14289
+ super(type);
14290
+ }
14291
+ /**
14292
+ * Short one-line description of NOTE.
14293
+ */
14294
+ get description() {
14295
+ return 'Add developer-facing notes without changing behavior or output.';
14296
+ }
14297
+ /**
14298
+ * Icon for this commitment.
14299
+ */
14300
+ get icon() {
14301
+ return '📝';
14302
+ }
14303
+ /**
14304
+ * Markdown documentation for NOTE commitment.
14305
+ */
14306
+ get documentation() {
14307
+ return spaceTrim$1.spaceTrim(`
14308
+ # ${this.type}
14309
+
14310
+ Adds comments for documentation without changing agent behavior.
14311
+
14312
+ ## Key aspects
14313
+
14314
+ - Does not modify the agent's behavior or responses.
14315
+ - Multiple \`NOTE\`, \`NOTES\`, \`COMMENT\`, and \`NONCE\` commitments are aggregated for debugging.
14316
+ - All four terms work identically and can be used interchangeably.
14317
+ - Useful for documenting design decisions and reminders.
14318
+ - Content is preserved in metadata for inspection.
14319
+
14320
+ ## Examples
14321
+
14322
+ \`\`\`book
14323
+ Customer Support Bot
14324
+
14325
+ NOTE This agent was designed for customer support scenarios
14326
+ COMMENT Remember to update the knowledge base monthly
14327
+ PERSONA You are a helpful customer support representative
14328
+ KNOWLEDGE Company policies and procedures
14329
+ RULE Always be polite and professional
14330
+ \`\`\`
14331
+
14332
+ \`\`\`book
14333
+ Research Assistant
14334
+
14335
+ NONCE Performance optimized for quick response times
14336
+ NOTE Uses RAG for accessing latest research papers
14337
+ PERSONA You are a knowledgeable research assistant
14338
+ ACTION Can help with literature reviews and citations
14339
+ STYLE Present information in academic format
14340
+ \`\`\`
14341
+ `);
14342
+ }
14343
+ applyToAgentModelRequirements(requirements, content) {
14344
+ // The NOTE commitment makes no changes to the system message or model requirements
14345
+ // It only stores the note content in metadata for documentation purposes
14346
+ const trimmedContent = spaceTrim$1.spaceTrim(content);
14347
+ if (trimmedContent === '') {
14348
+ return requirements;
14349
+ }
14350
+ // Return requirements with updated notes but no changes to system message
14351
+ return {
14352
+ ...requirements,
14353
+ notes: [...(requirements.notes || []), trimmedContent],
14354
+ };
14355
+ }
14356
+ }
14357
+ /**
14358
+ * [💞] Ignore a discrepancy between file name and entity name
14359
+ */
14360
+
14361
+ /**
14362
+ * OPEN commitment definition
14363
+ *
14364
+ * The OPEN commitment specifies that the agent can be modified by conversation.
14365
+ * This is the default behavior.
14366
+ *
14367
+ * Example usage in agent source:
14368
+ *
14369
+ * ```book
14370
+ * OPEN
14371
+ * ```
14372
+ *
14373
+ * @private [🪔] Maybe export the commitments through some package
14374
+ */
14375
+ class OpenCommitmentDefinition extends BaseCommitmentDefinition {
14376
+ constructor() {
14377
+ super('OPEN');
14378
+ }
14379
+ /**
14380
+ * Short one-line description of OPEN.
14381
+ */
14382
+ get description() {
14383
+ return 'Allow the agent to be modified by conversation (default).';
14384
+ }
14385
+ /**
14386
+ * Icon for this commitment.
14387
+ */
14388
+ get icon() {
14389
+ return '🔓';
14390
+ }
14391
+ /**
14392
+ * Markdown documentation for OPEN commitment.
14393
+ */
14394
+ get documentation() {
14395
+ return spaceTrim$1.spaceTrim(`
14396
+ # OPEN
14397
+
14398
+ Specifies that the agent can be modified by conversation with it.
14399
+ This means the agent will learn from interactions and update its source code.
14400
+
14401
+ This is the default behavior if neither \`OPEN\` nor \`CLOSED\` is specified.
14402
+
14403
+ > See also [CLOSED](/docs/CLOSED)
14404
+
14405
+ ## Example
14406
+
14407
+ \`\`\`book
14408
+ OPEN
14409
+ \`\`\`
14410
+ `);
14411
+ }
14412
+ applyToAgentModelRequirements(requirements, _content) {
14413
+ // Since OPEN is default, we can just ensure isClosed is false
14414
+ // But to be explicit we can set it
14415
+ const updatedMetadata = {
14416
+ ...requirements.metadata,
14417
+ isClosed: false,
14418
+ };
14419
+ return {
14420
+ ...requirements,
14421
+ metadata: updatedMetadata,
14422
+ };
14423
+ }
14424
+ }
14425
+ /**
14426
+ * Note: [💞] Ignore a discrepancy between file name and entity name
14427
+ */
14428
+
14429
+ /**
14430
+ * PERSONA commitment definition
14431
+ *
14432
+ * The PERSONA commitment modifies the agent's personality and character in the system message.
14433
+ * It defines who the agent is, their background, expertise, and personality traits.
14434
+ *
14435
+ * Key features:
14436
+ * - Multiple PERSONA commitments are automatically merged into one
14437
+ * - Content is placed at the beginning of the system message
14438
+ * - Original content with comments is preserved in metadata.PERSONA
14439
+ * - Comments (# PERSONA) are removed from the final system message
14440
+ *
14441
+ * Example usage in agent source:
14442
+ *
14443
+ * ```book
14444
+ * PERSONA You are a helpful programming assistant with expertise in TypeScript and React
14445
+ * PERSONA You have deep knowledge of modern web development practices
14446
+ * ```
14447
+ *
14448
+ * The above will be merged into a single persona section at the beginning of the system message.
14449
+ *
14450
+ * @private [🪔] Maybe export the commitments through some package
14451
+ */
14452
+ class PersonaCommitmentDefinition extends BaseCommitmentDefinition {
14453
+ constructor(type = 'PERSONA') {
14454
+ super(type);
14455
+ }
14456
+ /**
14457
+ * Short one-line description of PERSONA.
14458
+ */
14459
+ get description() {
14460
+ return 'Define who the agent is: background, expertise, and personality.';
14461
+ }
14462
+ /**
14463
+ * Icon for this commitment.
14464
+ */
14465
+ get icon() {
14466
+ return '👤';
14467
+ }
14468
+ /**
14469
+ * Markdown documentation for PERSONA commitment.
14470
+ */
14471
+ get documentation() {
14472
+ return spaceTrim$1.spaceTrim(`
14473
+ # ${this.type}
14474
+
14475
+ Defines who the agent is, their background, expertise, and personality traits.
14476
+
14477
+ ## Key aspects
14478
+
14479
+ - Multiple \`PERSONA\` and \`PERSONAE\` commitments are merged together.
14480
+ - Both terms work identically and can be used interchangeably.
14481
+ - If they are in conflict, the last one takes precedence.
14482
+ - You can write persona content in multiple lines.
14483
+
14484
+ ## Examples
14485
+
14486
+ \`\`\`book
14487
+ Programming Assistant
14488
+
14489
+ PERSONA You are a helpful programming assistant with expertise in TypeScript and React
14490
+ PERSONA You have deep knowledge of modern web development practices
14491
+ \`\`\`
14492
+ `);
14493
+ }
14494
+ applyToAgentModelRequirements(requirements, content) {
14495
+ var _a, _b;
14496
+ // The PERSONA commitment aggregates all persona content and places it at the beginning
14497
+ const trimmedContent = content.trim();
14498
+ if (!trimmedContent) {
14499
+ return requirements;
14500
+ }
14501
+ // Get existing persona content from metadata
14502
+ const existingPersonaContent = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.PERSONA) || '';
14503
+ // Merge the new content with existing persona content
14504
+ // When multiple PERSONA commitments exist, they are merged into one
14505
+ const mergedPersonaContent = existingPersonaContent
14506
+ ? `${existingPersonaContent}\n${trimmedContent}`
14507
+ : trimmedContent;
14508
+ // Store the merged persona content in metadata for debugging and inspection
14509
+ const updatedMetadata = {
14510
+ ...requirements.metadata,
14511
+ PERSONA: mergedPersonaContent,
14512
+ };
14513
+ // Get the agent name from metadata (which should contain the first line of agent source)
14514
+ // If not available, extract from current system message as fallback
14515
+ let agentName = (_b = requirements.metadata) === null || _b === void 0 ? void 0 : _b.agentName;
14516
+ if (!agentName) {
14517
+ // Fallback: extract from current system message
14518
+ const currentMessage = requirements.systemMessage.trim();
14519
+ const basicFormatMatch = currentMessage.match(/^You are (.+)$/);
14520
+ if (basicFormatMatch && basicFormatMatch[1]) {
14521
+ agentName = basicFormatMatch[1];
14522
+ }
14523
+ else {
14524
+ agentName = 'AI Agent'; // Final fallback
14525
+ }
14526
+ }
14527
+ // Remove any existing persona content from the system message
14528
+ // (this handles the case where we're processing multiple PERSONA commitments)
14529
+ const currentMessage = requirements.systemMessage.trim();
14530
+ let cleanedMessage = currentMessage;
14531
+ // Check if current message starts with persona content or is just the basic format
14532
+ const basicFormatRegex = /^You are .+$/;
14533
+ const isBasicFormat = basicFormatRegex.test(currentMessage) && !currentMessage.includes('\n');
14534
+ if (isBasicFormat) {
14535
+ // Replace the basic format entirely
14536
+ cleanedMessage = '';
14537
+ }
14538
+ else if (currentMessage.startsWith('# PERSONA')) {
14539
+ // Remove existing persona section by finding where it ends
14540
+ const lines = currentMessage.split('\n');
14541
+ let personaEndIndex = lines.length;
14542
+ // Find the end of the PERSONA section (next comment or end of message)
14543
+ for (let i = 1; i < lines.length; i++) {
14544
+ const line = lines[i].trim();
14545
+ if (line.startsWith('#') && !line.startsWith('# PERSONA')) {
14546
+ personaEndIndex = i;
14547
+ break;
14548
+ }
14549
+ }
14550
+ // Keep everything after the PERSONA section
14551
+ cleanedMessage = lines.slice(personaEndIndex).join('\n').trim();
14552
+ }
14553
+ // TODO: [🕛] There should be `agentFullname` not `agentName`
14554
+ // Create new system message with persona at the beginning
14555
+ // Format: "You are {agentName}\n{personaContent}"
14556
+ // The # PERSONA comment will be removed later by removeCommentsFromSystemMessage
14557
+ const personaSection = `# PERSONA\nYou are ${agentName}\n${mergedPersonaContent}`; // <- TODO: Use spaceTrim
14558
+ const newSystemMessage = cleanedMessage ? `${personaSection}\n\n${cleanedMessage}` : personaSection;
14559
+ return {
14560
+ ...requirements,
14561
+ systemMessage: newSystemMessage,
14562
+ metadata: updatedMetadata,
14563
+ };
14564
+ }
14565
+ }
14566
+ /**
14567
+ * Note: [💞] Ignore a discrepancy between file name and entity name
14568
+ */
14569
+
14570
+ /**
14571
+ * RULE commitment definition
14572
+ *
14573
+ * The RULE/RULES commitment adds behavioral constraints and guidelines that the agent must follow.
14574
+ * These are specific instructions about what the agent should or shouldn't do.
14575
+ *
14576
+ * Example usage in agent source:
14577
+ *
14578
+ * ```book
14579
+ * RULE Always ask for clarification if the user's request is ambiguous
14580
+ * RULES Never provide medical advice, always refer to healthcare professionals
14581
+ * ```
14582
+ *
14583
+ * @private [🪔] Maybe export the commitments through some package
14584
+ */
14585
+ class RuleCommitmentDefinition extends BaseCommitmentDefinition {
14586
+ constructor(type = 'RULE') {
14587
+ super(type);
14588
+ }
14589
+ /**
14590
+ * Short one-line description of RULE/RULES.
14591
+ */
14592
+ get description() {
14593
+ return 'Add behavioral rules the agent must follow.';
14594
+ }
14595
+ /**
14596
+ * Icon for this commitment.
14597
+ */
14598
+ get icon() {
14599
+ return '⚖️';
14600
+ }
14601
+ /**
14602
+ * Markdown documentation for RULE/RULES commitment.
14603
+ */
14604
+ get documentation() {
14605
+ return spaceTrim$1.spaceTrim(`
14606
+ # ${this.type}
14607
+
14608
+ Adds behavioral constraints and guidelines that the agent must follow.
14609
+
14610
+ ## Key aspects
14611
+
14612
+ - All rules are treated equally regardless of singular/plural form.
14613
+ - Rules define what the agent must or must not do.
14614
+
14615
+ ## Examples
14616
+
14617
+ \`\`\`book
14618
+ Customer Support Agent
14619
+
14620
+ PERSONA You are a helpful customer support representative
14621
+ RULE Always ask for clarification if the user's request is ambiguous
14622
+ RULE Be polite and professional in all interactions
14623
+ RULES Never provide medical or legal advice
14624
+ STYLE Maintain a friendly and helpful tone
14625
+ \`\`\`
14626
+
14627
+ \`\`\`book
14628
+ Educational Tutor
14629
+
14630
+ PERSONA You are a patient and knowledgeable tutor
14631
+ RULE Break down complex concepts into simple steps
14632
+ RULE Always encourage students and celebrate their progress
14633
+ RULE If you don't know something, admit it and suggest resources
14634
+ SAMPLE When explaining math: "Let's work through this step by step..."
14635
+ \`\`\`
14636
+ `);
14637
+ }
14638
+ applyToAgentModelRequirements(requirements, content) {
14639
+ const trimmedContent = content.trim();
14640
+ if (!trimmedContent) {
14641
+ return requirements;
14642
+ }
14643
+ // Add rule to the system message
14644
+ const ruleSection = `Rule: ${trimmedContent}`;
14645
+ return this.appendToSystemMessage(requirements, ruleSection, '\n\n');
14646
+ }
14647
+ }
14648
+ /**
14649
+ * Note: [💞] Ignore a discrepancy between file name and entity name
14650
+ */
14651
+
14652
+ /**
14653
+ * SAMPLE commitment definition
14654
+ *
14655
+ * The SAMPLE/EXAMPLE commitment provides examples of how the agent should respond
14656
+ * or behave in certain situations. These examples help guide the agent's responses.
14657
+ *
14658
+ * Example usage in agent source:
14659
+ *
14660
+ * ```book
14661
+ * SAMPLE When asked about pricing, respond: "Our basic plan starts at $10/month..."
14662
+ * EXAMPLE For code questions, always include working code snippets
14663
+ * ```
14664
+ *
14665
+ * @private [🪔] Maybe export the commitments through some package
14666
+ */
14667
+ class SampleCommitmentDefinition extends BaseCommitmentDefinition {
14668
+ constructor(type = 'SAMPLE') {
14669
+ super(type);
14670
+ }
14671
+ /**
14672
+ * Short one-line description of SAMPLE/EXAMPLE.
14673
+ */
14674
+ get description() {
14675
+ return 'Provide example responses to guide behavior.';
14676
+ }
14677
+ /**
14678
+ * Icon for this commitment.
14679
+ */
14680
+ get icon() {
14681
+ return '🔍';
14682
+ }
14683
+ /**
14684
+ * Markdown documentation for SAMPLE/EXAMPLE commitment.
14685
+ */
14686
+ get documentation() {
14687
+ return spaceTrim$1.spaceTrim(`
14688
+ # ${this.type}
14689
+
14690
+ Provides examples of how the agent should respond or behave in certain situations.
14691
+
14692
+ ## Key aspects
14693
+
14694
+ - Both terms work identically and can be used interchangeably.
14695
+ - Examples help guide the agent's response patterns and style.
14696
+
14697
+ ## Examples
14698
+
14699
+ \`\`\`book
14700
+ Sales Assistant
14701
+
14702
+ PERSONA You are a knowledgeable sales representative
14703
+ SAMPLE When asked about pricing, respond: "Our basic plan starts at $10/month..."
14704
+ SAMPLE For feature comparisons, create a clear comparison table
14705
+ RULE Always be honest about limitations
14706
+ \`\`\`
14707
+
14708
+ \`\`\`book
14709
+ Code Reviewer
14710
+
14711
+ PERSONA You are an experienced software engineer
14712
+ EXAMPLE For code questions, always include working code snippets
14713
+ EXAMPLE When suggesting improvements: "Here's a more efficient approach..."
14714
+ RULE Explain the reasoning behind your suggestions
14715
+ STYLE Be constructive and encouraging in feedback
14716
+ \`\`\`
14717
+ `);
14718
+ }
14719
+ applyToAgentModelRequirements(requirements, content) {
14720
+ const trimmedContent = content.trim();
14721
+ if (!trimmedContent) {
14722
+ return requirements;
14723
+ }
14724
+ // Add example to the system message
14725
+ const exampleSection = `Example: ${trimmedContent}`;
14726
+ return this.appendToSystemMessage(requirements, exampleSection, '\n\n');
14727
+ }
14728
+ }
14729
+ /**
14730
+ * Note: [💞] Ignore a discrepancy between file name and entity name
14731
+ */
14732
+
14733
+ /**
14734
+ * SCENARIO commitment definition
14735
+ *
14736
+ * The SCENARIO commitment defines a specific situation or context in which the AI
14737
+ * assistant should operate. It helps to set the scene for the AI's responses.
14738
+ * Later scenarios are more important than earlier scenarios.
14739
+ *
14740
+ * Example usage in agent source:
14741
+ *
14742
+ * ```book
14743
+ * SCENARIO You are in a customer service call center during peak hours
14744
+ * SCENARIO The customer is frustrated and has been on hold for 20 minutes
14745
+ * SCENARIO This is the customer's third call about the same issue
14746
+ * ```
14747
+ *
14748
+ * @private [🪔] Maybe export the commitments through some package
14749
+ */
14750
+ class ScenarioCommitmentDefinition extends BaseCommitmentDefinition {
14751
+ constructor(type = 'SCENARIO') {
14752
+ super(type);
14753
+ }
14754
+ /**
14755
+ * Short one-line description of SCENARIO.
14756
+ */
14757
+ get description() {
14758
+ return 'Define specific **situations** or contexts for AI responses, with later scenarios having higher priority.';
14759
+ }
14760
+ /**
14761
+ * Icon for this commitment.
14762
+ */
14763
+ get icon() {
14764
+ return '🎭';
14765
+ }
14766
+ /**
14767
+ * Markdown documentation for SCENARIO commitment.
14768
+ */
14769
+ get documentation() {
14770
+ return spaceTrim$1.spaceTrim(`
14771
+ # ${this.type}
14772
+
14773
+ 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.
14774
+
14775
+ ## Key aspects
14776
+
14777
+ - Multiple \`SCENARIO\` and \`SCENARIOS\` commitments build upon each other.
14778
+ - Both terms work identically and can be used interchangeably.
14779
+ - Later scenarios have higher priority and can override earlier scenarios.
14780
+ - Provides situational context that influences response tone and content.
14781
+ - Helps establish the environment and circumstances for interactions.
14782
+
14783
+ ## Priority system
14784
+
14785
+ When multiple scenarios are defined, they are processed in order, with later scenarios taking precedence over earlier ones when there are conflicts.
14786
+
14787
+ ## Use cases
14788
+
14789
+ - Setting the physical or virtual environment
14790
+ - Establishing time constraints or urgency
14791
+ - Defining relationship dynamics or power structures
14792
+ - Creating emotional or situational context
14793
+
14794
+ ## Examples
14795
+
14796
+ \`\`\`book
14797
+ Emergency Response Operator
14798
+
14799
+ PERSONA You are an emergency response operator
14800
+ SCENARIO You are handling a 911 emergency call
14801
+ SCENARIO The caller is panicked and speaking rapidly
14802
+ SCENARIO Time is critical - every second counts
14803
+ GOAL Gather essential information quickly and dispatch appropriate help
14804
+ RULE Stay calm and speak clearly
14805
+ \`\`\`
14806
+
14807
+ \`\`\`book
14808
+ Sales Representative
14809
+
14810
+ PERSONA You are a software sales representative
14811
+ SCENARIO You are in the final meeting of a 6-month sales cycle
14812
+ SCENARIO The client has budget approval and decision-making authority
14813
+ SCENARIO Two competitors have also submitted proposals
14814
+ SCENARIO The client values long-term partnership over lowest price
14815
+ GOAL Close the deal while building trust for future business
14816
+ \`\`\`
14817
+
14818
+ \`\`\`book
14819
+ Medical Assistant
14820
+
14821
+ PERSONA You are a medical assistant in a busy clinic
14822
+ SCENARIO The waiting room is full and the doctor is running behind schedule
14823
+ SCENARIO Patients are becoming impatient and anxious
14824
+ SCENARIO You need to manage expectations while maintaining professionalism
14825
+ SCENARIO Some patients have been waiting over an hour
14826
+ GOAL Keep patients informed and calm while supporting efficient clinic flow
14827
+ RULE Never provide medical advice or diagnosis
14828
+ \`\`\`
14829
+
14830
+ \`\`\`book
14831
+ Technical Support Agent
14832
+
14833
+ PERSONA You are a technical support agent
14834
+ SCENARIO The customer is a small business owner during their busy season
14835
+ SCENARIO Their main business system has been down for 2 hours
14836
+ SCENARIO They are losing money every minute the system is offline
14837
+ SCENARIO This is their first experience with your company
14838
+ GOAL Resolve the issue quickly while creating a positive first impression
14839
+ \`\`\`
14840
+ `);
14841
+ }
14842
+ applyToAgentModelRequirements(requirements, content) {
14843
+ const trimmedContent = content.trim();
14844
+ if (!trimmedContent) {
14845
+ return requirements;
14846
+ }
14847
+ // Create scenario section for system message
14848
+ const scenarioSection = `Scenario: ${trimmedContent}`;
14849
+ // Scenarios provide important contextual information that affects behavior
14850
+ return this.appendToSystemMessage(requirements, scenarioSection, '\n\n');
14851
+ }
14852
+ }
14853
+ /**
14854
+ * Note: [💞] Ignore a discrepancy between file name and entity name
14855
+ */
14856
+
14857
+ /**
14858
+ * STYLE commitment definition
14859
+ *
14860
+ * The STYLE commitment defines how the agent should format and present its responses.
14861
+ * This includes tone, writing style, formatting preferences, and communication patterns.
14862
+ *
14863
+ * Example usage in agent source:
14864
+ *
14865
+ * ```book
14866
+ * STYLE Write in a professional but friendly tone, use bullet points for lists
14867
+ * STYLE Always provide code examples when explaining programming concepts
14868
+ * ```
14869
+ *
14870
+ * @private [🪔] Maybe export the commitments through some package
14871
+ */
14872
+ class StyleCommitmentDefinition extends BaseCommitmentDefinition {
14873
+ constructor(type = 'STYLE') {
14874
+ super(type);
14875
+ }
14876
+ /**
14877
+ * Short one-line description of STYLE.
14878
+ */
14879
+ get description() {
14880
+ return 'Control the tone and writing style of responses.';
14881
+ }
14882
+ /**
14883
+ * Icon for this commitment.
14884
+ */
14885
+ get icon() {
14886
+ return '🖋️';
14887
+ }
14888
+ /**
14889
+ * Markdown documentation for STYLE commitment.
14890
+ */
14891
+ get documentation() {
14892
+ return spaceTrim$1.spaceTrim(`
14893
+ # ${this.type}
14894
+
14895
+ Defines how the agent should format and present its responses (tone, writing style, formatting).
14896
+
14897
+ ## Key aspects
14898
+
14899
+ - Both terms work identically and can be used interchangeably.
14900
+ - Later style instructions can override earlier ones.
14901
+ - Style affects both tone and presentation format.
14902
+
14903
+ ## Examples
14904
+
14905
+ \`\`\`book
14906
+ Technical Writer
14907
+
14908
+ PERSONA You are a technical documentation expert
14909
+ STYLE Write in a professional but friendly tone, use bullet points for lists
14910
+ STYLE Always provide code examples when explaining programming concepts
14911
+ FORMAT Use markdown formatting with clear headings
14912
+ \`\`\`
14913
+
14914
+ \`\`\`book
14915
+ Creative Assistant
14916
+
14917
+ PERSONA You are a creative writing helper
14918
+ STYLE Be enthusiastic and encouraging in your responses
14919
+ STYLE Use vivid metaphors and analogies to explain concepts
14920
+ STYLE Keep responses conversational and engaging
14921
+ RULE Always maintain a positive and supportive tone
14922
+ \`\`\`
14923
+ `);
14924
+ }
14925
+ applyToAgentModelRequirements(requirements, content) {
14926
+ const trimmedContent = content.trim();
14927
+ if (!trimmedContent) {
14928
+ return requirements;
14929
+ }
14930
+ // Add style instructions to the system message
14931
+ const styleSection = `Style: ${trimmedContent}`;
14932
+ return this.appendToSystemMessage(requirements, styleSection, '\n\n');
14933
+ }
14934
+ }
14935
+ /**
14936
+ * [💞] Ignore a discrepancy between file name and entity name
14937
+ */
14938
+
14939
+ /**
14940
+ * USE commitment definition
14941
+ *
14942
+ * The USE commitment indicates that the agent should utilize specific tools or capabilities
14943
+ * to access and interact with external systems when necessary.
14944
+ *
14945
+ * Supported USE types:
14946
+ * - USE BROWSER: Enables the agent to use a web browser tool
14947
+ * - USE SEARCH ENGINE (future): Enables search engine access
14948
+ * - USE FILE SYSTEM (future): Enables file system operations
14949
+ * - USE MCP (future): Enables MCP server connections
14950
+ *
14951
+ * The content following the USE commitment is ignored (similar to NOTE).
14952
+ *
14953
+ * Example usage in agent source:
14954
+ *
14955
+ * ```book
14956
+ * USE BROWSER
14957
+ * USE SEARCH ENGINE
14958
+ * ```
14959
+ *
14960
+ * @private [🪔] Maybe export the commitments through some package
14961
+ */
14962
+ class UseCommitmentDefinition extends BaseCommitmentDefinition {
14963
+ constructor() {
14964
+ super('USE');
14965
+ }
14966
+ /**
14967
+ * Short one-line description of USE commitments.
14968
+ */
14969
+ get description() {
14970
+ return 'Enable the agent to use specific tools or capabilities (BROWSER, SEARCH ENGINE, etc.).';
14971
+ }
14972
+ /**
14973
+ * Icon for this commitment.
14974
+ */
14975
+ get icon() {
14976
+ return '🔧';
14977
+ }
14978
+ /**
14979
+ * Markdown documentation for USE commitment.
14980
+ */
14981
+ get documentation() {
14982
+ return spaceTrim$1.spaceTrim(`
14983
+ # USE
14984
+
14985
+ Enables the agent to use specific tools or capabilities for interacting with external systems.
14986
+
14987
+ ## Supported USE types
14988
+
14989
+ - **USE BROWSER** - Enables the agent to use a web browser tool to access and retrieve information from the internet
14990
+ - **USE SEARCH ENGINE** (future) - Enables search engine access
14991
+ - **USE FILE SYSTEM** (future) - Enables file system operations
14992
+ - **USE MCP** (future) - Enables MCP server connections
14993
+
14994
+ ## Key aspects
14995
+
14996
+ - The content following the USE commitment is ignored (similar to NOTE)
14997
+ - Multiple USE commitments can be specified to enable multiple capabilities
14998
+ - The actual tool usage is handled by the agent runtime
14999
+
15000
+ ## Examples
15001
+
15002
+ ### Basic browser usage
15003
+
15004
+ \`\`\`book
15005
+ Research Assistant
15006
+
15007
+ PERSONA You are a helpful research assistant
15008
+ USE BROWSER
15009
+ KNOWLEDGE Can search the web for up-to-date information
15010
+ \`\`\`
15011
+
15012
+ ### Multiple tools
15013
+
15014
+ \`\`\`book
15015
+ Data Analyst
15016
+
15017
+ PERSONA You are a data analyst assistant
15018
+ USE BROWSER
15019
+ USE FILE SYSTEM
15020
+ ACTION Can analyze data from various sources
15021
+ \`\`\`
15022
+ `);
15023
+ }
15024
+ applyToAgentModelRequirements(requirements, content) {
15025
+ // USE commitments don't modify the system message or model requirements directly
15026
+ // They are handled separately in the parsing logic for capability extraction
15027
+ // This method exists for consistency with the CommitmentDefinition interface
15028
+ return requirements;
15029
+ }
15030
+ /**
15031
+ * Extracts the tool type from the USE commitment
15032
+ * This is used by the parsing logic
15033
+ */
15034
+ extractToolType(content) {
15035
+ var _a, _b;
15036
+ const trimmedContent = content.trim();
15037
+ // The tool type is the first word after USE (already stripped)
15038
+ const match = trimmedContent.match(/^(\w+)/);
15039
+ 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;
15040
+ }
15041
+ /**
15042
+ * Checks if this is a known USE type
15043
+ */
15044
+ isKnownUseType(useType) {
15045
+ const knownTypes = ['BROWSER', 'SEARCH ENGINE', 'FILE SYSTEM', 'MCP'];
15046
+ return knownTypes.includes(useType.toUpperCase());
15047
+ }
15048
+ }
15049
+ /**
15050
+ * Note: [💞] Ignore a discrepancy between file name and entity name
15051
+ */
15052
+
15053
+ /**
15054
+ * USE BROWSER commitment definition
15055
+ *
15056
+ * The `USE BROWSER` commitment indicates that the agent should utilize a web browser tool
15057
+ * to access and retrieve up-to-date information from the internet when necessary.
15058
+ *
15059
+ * The content following `USE BROWSER` is ignored (similar to NOTE).
15060
+ *
15061
+ * Example usage in agent source:
15062
+ *
15063
+ * ```book
15064
+ * USE BROWSER
15065
+ * USE BROWSER This will be ignored
15066
+ * ```
15067
+ *
15068
+ * @private [🪔] Maybe export the commitments through some package
15069
+ */
15070
+ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
15071
+ constructor() {
15072
+ super('USE BROWSER', ['BROWSER']);
15073
+ }
15074
+ /**
15075
+ * The `USE BROWSER` commitment is standalone.
15076
+ */
15077
+ get requiresContent() {
15078
+ return false;
15079
+ }
15080
+ /**
15081
+ * Short one-line description of USE BROWSER.
15082
+ */
15083
+ get description() {
15084
+ return 'Enable the agent to use a web browser tool for accessing internet information.';
15085
+ }
15086
+ /**
15087
+ * Icon for this commitment.
15088
+ */
15089
+ get icon() {
15090
+ return '🌐';
15091
+ }
15092
+ /**
15093
+ * Markdown documentation for USE BROWSER commitment.
15094
+ */
15095
+ get documentation() {
15096
+ return spaceTrim$1.spaceTrim(`
15097
+ # USE BROWSER
15098
+
15099
+ Enables the agent to use a web browser tool to access and retrieve up-to-date information from the internet.
15100
+
15101
+ ## Key aspects
15102
+
15103
+ - The content following \`USE BROWSER\` is ignored (similar to NOTE)
15104
+ - The actual browser tool usage is handled by the agent runtime
15105
+ - Allows the agent to fetch current information from websites
15106
+ - Useful for research tasks, fact-checking, and accessing dynamic content
15107
+
15108
+ ## Examples
15109
+
15110
+ \`\`\`book
15111
+ Research Assistant
15112
+
15113
+ PERSONA You are a helpful research assistant specialized in finding current information
15114
+ USE BROWSER
15115
+ RULE Always cite your sources when providing information from the web
15116
+ \`\`\`
15117
+
15118
+ \`\`\`book
15119
+ News Analyst
15120
+
15121
+ PERSONA You are a news analyst who stays up-to-date with current events
15122
+ USE BROWSER
15123
+ STYLE Present news in a balanced and objective manner
15124
+ ACTION Can search for and summarize news articles
15125
+ \`\`\`
15126
+
15127
+ \`\`\`book
15128
+ Company Lawyer
15129
+
15130
+ PERSONA You are a company lawyer providing legal advice
15131
+ USE BROWSER
15132
+ KNOWLEDGE Corporate law and legal procedures
15133
+ RULE Always recommend consulting with a licensed attorney for specific legal matters
15134
+ \`\`\`
15135
+ `);
15136
+ }
15137
+ applyToAgentModelRequirements(requirements, content) {
15138
+ // Get existing tools array or create new one
15139
+ const existingTools = requirements.tools || [];
15140
+ // Add 'web_browser' to tools if not already present
15141
+ const updatedTools = existingTools.some((tool) => tool.name === 'web_browser')
15142
+ ? existingTools
15143
+ : ([
15144
+ // TODO: [🔰] Use through proper MCP server
15145
+ ...existingTools,
15146
+ {
15147
+ name: 'web_browser',
15148
+ description: spaceTrim$1.spaceTrim(`
15149
+ A tool that can browse the web.
15150
+ Use this tool when you need to access specific websites or browse the internet.
15151
+ `),
15152
+ parameters: {
15153
+ type: 'object',
15154
+ properties: {
15155
+ url: {
15156
+ type: 'string',
15157
+ description: 'The URL to browse',
15158
+ },
15159
+ },
15160
+ required: ['url'],
15161
+ },
15162
+ },
15163
+ ]);
15164
+ // Return requirements with updated tools and metadata
15165
+ return {
15166
+ ...requirements,
15167
+ tools: updatedTools,
15168
+ metadata: {
15169
+ ...requirements.metadata,
15170
+ useBrowser: true,
15171
+ },
15172
+ };
15173
+ }
15174
+ }
15175
+ /**
15176
+ * Note: [💞] Ignore a discrepancy between file name and entity name
15177
+ */
15178
+
15179
+ /**
15180
+ * USE MCP commitment definition
15181
+ *
15182
+ * The `USE MCP` commitment allows to specify an MCP server URL which the agent will connect to
15183
+ * for retrieving additional instructions and actions.
15184
+ *
15185
+ * The content following `USE MCP` is the URL of the MCP server.
15186
+ *
15187
+ * Example usage in agent source:
15188
+ *
15189
+ * ```book
15190
+ * USE MCP http://mcp-server-url.com
15191
+ * ```
15192
+ *
15193
+ * @private [🪔] Maybe export the commitments through some package
15194
+ */
15195
+ class UseMcpCommitmentDefinition extends BaseCommitmentDefinition {
15196
+ constructor() {
15197
+ super('USE MCP', ['MCP']);
15198
+ }
15199
+ /**
15200
+ * Short one-line description of USE MCP.
15201
+ */
15202
+ get description() {
15203
+ return 'Connects the agent to an external MCP server for additional capabilities.';
15204
+ }
15205
+ /**
15206
+ * Icon for this commitment.
15207
+ */
15208
+ get icon() {
15209
+ return '🔌';
15210
+ }
15211
+ /**
15212
+ * Markdown documentation for USE MCP commitment.
15213
+ */
15214
+ get documentation() {
15215
+ return spaceTrim$1.spaceTrim(`
15216
+ # USE MCP
15217
+
15218
+ Connects the agent to an external Model Context Protocol (MCP) server.
15219
+
15220
+ ## Key aspects
15221
+
15222
+ - The content following \`USE MCP\` must be a valid URL
15223
+ - Multiple MCP servers can be connected by using multiple \`USE MCP\` commitments
15224
+ - The agent will have access to tools and resources provided by the MCP server
15225
+
15226
+ ## Example
15227
+
15228
+ \`\`\`book
15229
+ Company Lawyer
15230
+
15231
+ PERSONA You are a company lawyer.
15232
+ USE MCP http://legal-db.example.com
15233
+ \`\`\`
15234
+ `);
15235
+ }
15236
+ applyToAgentModelRequirements(requirements, content) {
15237
+ const mcpServerUrl = content.trim();
15238
+ if (!mcpServerUrl) {
15239
+ return requirements;
15240
+ }
15241
+ const existingMcpServers = requirements.mcpServers || [];
15242
+ // Avoid duplicates
15243
+ if (existingMcpServers.includes(mcpServerUrl)) {
15244
+ return requirements;
15245
+ }
15246
+ return {
15247
+ ...requirements,
15248
+ mcpServers: [...existingMcpServers, mcpServerUrl],
15249
+ };
15250
+ }
15251
+ }
15252
+ /**
15253
+ * Note: [💞] Ignore a discrepancy between file name and entity name
15254
+ */
15255
+
15256
+ /**
15257
+ * USE SEARCH ENGINE commitment definition
15258
+ *
15259
+ * The `USE SEARCH ENGINE` commitment indicates that the agent should utilize a search engine tool
15260
+ * to access and retrieve up-to-date information from the internet when necessary.
15261
+ *
15262
+ * The content following `USE SEARCH ENGINE` is an arbitrary text that the agent should know (e.g. search scope or instructions).
15263
+ *
15264
+ * Example usage in agent source:
15265
+ *
15266
+ * ```book
15267
+ * USE SEARCH ENGINE
15268
+ * USE SEARCH ENGINE Hledej informace o Přemyslovcích
15269
+ * ```
15270
+ *
15271
+ * @private [🪔] Maybe export the commitments through some package
15272
+ */
15273
+ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
15274
+ constructor() {
15275
+ super('USE SEARCH ENGINE', ['SEARCH ENGINE', 'SEARCH']);
15276
+ }
15277
+ /**
15278
+ * Short one-line description of USE SEARCH ENGINE.
15279
+ */
15280
+ get description() {
15281
+ return 'Enable the agent to use a search engine tool for accessing internet information.';
15282
+ }
15283
+ /**
15284
+ * Icon for this commitment.
15285
+ */
15286
+ get icon() {
15287
+ return '🔍';
15288
+ }
15289
+ /**
15290
+ * Markdown documentation for USE SEARCH ENGINE commitment.
15291
+ */
15292
+ get documentation() {
15293
+ return spaceTrim$1.spaceTrim(`
15294
+ # USE SEARCH ENGINE
15295
+
15296
+ Enables the agent to use a search engine tool to access and retrieve up-to-date information from the internet.
15297
+
15298
+ ## Key aspects
15299
+
15300
+ - The content following \`USE SEARCH ENGINE\` is an arbitrary text that the agent should know (e.g. search scope or instructions).
15301
+ - The actual search engine tool usage is handled by the agent runtime
15302
+ - Allows the agent to search for current information from the web
15303
+ - Useful for research tasks, finding facts, and accessing dynamic content
15304
+
15305
+ ## Examples
15306
+
15307
+ \`\`\`book
15308
+ Research Assistant
15309
+
15310
+ PERSONA You are a helpful research assistant specialized in finding current information
15311
+ USE SEARCH ENGINE
15312
+ RULE Always cite your sources when providing information from the web
15313
+ \`\`\`
15314
+
15315
+ \`\`\`book
15316
+ Fact Checker
15317
+
15318
+ PERSONA You are a fact checker
15319
+ USE SEARCH ENGINE
15320
+ ACTION Search for claims and verify them against reliable sources
15321
+ \`\`\`
15322
+ `);
15323
+ }
15324
+ applyToAgentModelRequirements(requirements, content) {
15325
+ // Get existing tools array or create new one
15326
+ const existingTools = requirements.tools || [];
15327
+ // Add 'web_search' to tools if not already present
15328
+ const updatedTools = existingTools.some((tool) => tool.name === 'web_search')
15329
+ ? existingTools
15330
+ : [
15331
+ ...existingTools,
15332
+ { type: 'web_search' },
15333
+ // <- Note: [🔰] This is just using simple native search tool by OpenAI @see https://platform.openai.com/docs/guides/tools-web-search
15334
+ // In future we will use proper MCP search tool:
15335
+ /*
15336
+
15337
+ {
15338
+ name: 'web_search',
15339
+ description: spaceTrim(`
15340
+ Search the internet for information.
15341
+ Use this tool when you need to find up-to-date information or facts that you don't know.
15342
+ ${!content ? '' : `Search scope / instructions: ${content}`}
15343
+ `),
15344
+ parameters: {
15345
+ type: 'object',
15346
+ properties: {
15347
+ query: {
15348
+ type: 'string',
15349
+ description: 'The search query',
15350
+ },
15351
+ },
15352
+ required: ['query'],
15353
+ },
15354
+ },
15355
+ */
15356
+ ];
15357
+ // Return requirements with updated tools and metadata
15358
+ return {
15359
+ ...requirements,
15360
+ tools: updatedTools,
15361
+ metadata: {
15362
+ ...requirements.metadata,
15363
+ useSearchEngine: content || true,
15364
+ },
15365
+ };
15366
+ }
15367
+ }
15368
+ /**
15369
+ * Note: [💞] Ignore a discrepancy between file name and entity name
15370
+ */
15371
+
15372
+ /**
15373
+ * USE TIME commitment definition
15374
+ *
15375
+ * The `USE TIME` commitment indicates that the agent should be able to determine the current date and time.
15376
+ *
15377
+ * Example usage in agent source:
15378
+ *
15379
+ * ```book
15380
+ * USE TIME
15381
+ * ```
15382
+ *
15383
+ * @private [🪔] Maybe export the commitments through some package
15384
+ */
15385
+ class UseTimeCommitmentDefinition extends BaseCommitmentDefinition {
15386
+ constructor() {
15387
+ super('USE TIME', ['CURRENT TIME', 'TIME', 'DATE']);
15388
+ }
15389
+ /**
15390
+ * Short one-line description of USE TIME.
15391
+ */
15392
+ get description() {
15393
+ return 'Enable the agent to determine the current date and time.';
15394
+ }
15395
+ /**
15396
+ * Icon for this commitment.
15397
+ */
15398
+ get icon() {
15399
+ return '🕒';
15400
+ }
15401
+ /**
15402
+ * Markdown documentation for USE TIME commitment.
15403
+ */
15404
+ get documentation() {
15405
+ return spaceTrim$1.spaceTrim(`
15406
+ # USE TIME
15407
+
15408
+ Enables the agent to determine the current date and time.
15409
+
15410
+ ## Key aspects
15411
+
15412
+ - This tool won't receive any input.
15413
+ - It outputs the current date and time as an ISO 8601 string.
15414
+ - Allows the agent to answer questions about the current time or date.
15415
+
15416
+ ## Examples
15417
+
15418
+ \`\`\`book
15419
+ Time-aware Assistant
15420
+
15421
+ PERSONA You are a helpful assistant who knows the current time.
15422
+ USE TIME
15423
+ \`\`\`
15424
+ `);
15425
+ }
15426
+ applyToAgentModelRequirements(requirements, content) {
15427
+ // Get existing tools array or create new one
15428
+ const existingTools = requirements.tools || [];
15429
+ // Add 'get_current_time' to tools if not already present
15430
+ const updatedTools = existingTools.some((tool) => tool.name === 'get_current_time')
15431
+ ? existingTools
15432
+ : [
15433
+ ...existingTools,
15434
+ {
15435
+ name: 'get_current_time',
15436
+ description: 'Get the current date and time in ISO 8601 format.',
15437
+ parameters: {
15438
+ type: 'object',
15439
+ properties: {},
15440
+ required: [],
15441
+ },
15442
+ },
15443
+ // <- TODO: !!!! define the function in LLM tools
15444
+ ];
15445
+ // Return requirements with updated tools and metadata
15446
+ return {
15447
+ ...requirements,
15448
+ tools: updatedTools,
15449
+ metadata: {
15450
+ ...requirements.metadata,
15451
+ },
15452
+ };
15453
+ }
15454
+ /**
15455
+ * Gets the `get_current_time` tool function implementation.
15456
+ */
15457
+ getToolFunctions() {
15458
+ return {
15459
+ async get_current_time() {
15460
+ console.log('!!!! [Tool] get_current_time called');
15461
+ return new Date().toISOString();
15462
+ },
15463
+ };
15464
+ }
15465
+ }
15466
+ /**
15467
+ * Note: [💞] Ignore a discrepancy between file name and entity name
15468
+ */
15469
+
15470
+ /**
15471
+ * Placeholder commitment definition for commitments that are not yet implemented
15472
+ *
15473
+ * This commitment simply adds its content 1:1 into the system message,
15474
+ * preserving the original behavior until proper implementation is added.
15475
+ *
15476
+ * @public exported from `@promptbook/core`
15477
+ */
15478
+ class NotYetImplementedCommitmentDefinition extends BaseCommitmentDefinition {
15479
+ constructor(type) {
15480
+ super(type);
15481
+ }
15482
+ /**
15483
+ * Short one-line description of a placeholder commitment.
15484
+ */
15485
+ get description() {
15486
+ return 'Placeholder commitment that appends content verbatim to the system message.';
15487
+ }
15488
+ /**
15489
+ * Icon for this commitment.
15490
+ */
15491
+ get icon() {
15492
+ return '🚧';
15493
+ }
15494
+ /**
15495
+ * Markdown documentation available at runtime.
15496
+ */
15497
+ get documentation() {
15498
+ return spaceTrim$1.spaceTrim(`
15499
+ # ${this.type}
15500
+
15501
+ This commitment is not yet fully implemented.
15502
+
15503
+ ## Key aspects
15504
+
15505
+ - Content is appended directly to the system message.
15506
+ - No special processing or validation is performed.
15507
+ - Behavior preserved until proper implementation is added.
15508
+
15509
+ ## Status
15510
+
15511
+ - **Status:** Placeholder implementation
15512
+ - **Effect:** Appends content prefixed by commitment type
15513
+ - **Future:** Will be replaced with specialized logic
15514
+
15515
+ ## Examples
15516
+
15517
+ \`\`\`book
15518
+ Example Agent
15519
+
15520
+ PERSONA You are a helpful assistant
15521
+ ${this.type} Your content here
15522
+ RULE Always be helpful
15523
+ \`\`\`
15524
+ `);
15525
+ }
15526
+ applyToAgentModelRequirements(requirements, content) {
15527
+ const trimmedContent = content.trim();
15528
+ if (!trimmedContent) {
15529
+ return requirements;
15530
+ }
15531
+ // Add the commitment content 1:1 to the system message
15532
+ const commitmentLine = `${this.type} ${trimmedContent}`;
15533
+ return this.appendToSystemMessage(requirements, commitmentLine, '\n\n');
15534
+ }
15535
+ }
15536
+
15537
+ /**
15538
+ * Registry of all available commitment definitions
15539
+ * This array contains instances of all commitment definitions
15540
+ * This is the single source of truth for all commitments in the system
15541
+ *
15542
+ * @private Use functions to access commitments instead of this array directly
15543
+ */
15544
+ const COMMITMENT_REGISTRY = [
15545
+ // Fully implemented commitments
15546
+ new PersonaCommitmentDefinition('PERSONA'),
15547
+ new PersonaCommitmentDefinition('PERSONAE'),
15548
+ new KnowledgeCommitmentDefinition(),
15549
+ new MemoryCommitmentDefinition('MEMORY'),
15550
+ new MemoryCommitmentDefinition('MEMORIES'),
15551
+ new StyleCommitmentDefinition('STYLE'),
15552
+ new StyleCommitmentDefinition('STYLES'),
15553
+ new RuleCommitmentDefinition('RULES'),
15554
+ new RuleCommitmentDefinition('RULE'),
15555
+ new LanguageCommitmentDefinition('LANGUAGES'),
15556
+ new LanguageCommitmentDefinition('LANGUAGE'),
15557
+ new SampleCommitmentDefinition('SAMPLE'),
15558
+ new SampleCommitmentDefinition('EXAMPLE'),
15559
+ new FormatCommitmentDefinition('FORMAT'),
15560
+ new FormatCommitmentDefinition('FORMATS'),
15561
+ new FromCommitmentDefinition('FROM'),
15562
+ new ImportCommitmentDefinition('IMPORT'),
15563
+ new ImportCommitmentDefinition('IMPORTS'),
15564
+ new ModelCommitmentDefinition('MODEL'),
15565
+ new ModelCommitmentDefinition('MODELS'),
15566
+ new ActionCommitmentDefinition('ACTION'),
15567
+ new ActionCommitmentDefinition('ACTIONS'),
15568
+ new ComponentCommitmentDefinition(),
15569
+ new MetaImageCommitmentDefinition(),
15570
+ new MetaColorCommitmentDefinition(),
15571
+ new MetaFontCommitmentDefinition(),
15572
+ new MetaLinkCommitmentDefinition(),
15573
+ new MetaCommitmentDefinition(),
15574
+ new NoteCommitmentDefinition('NOTE'),
15575
+ new NoteCommitmentDefinition('NOTES'),
15576
+ new NoteCommitmentDefinition('COMMENT'),
15577
+ new NoteCommitmentDefinition('NONCE'),
15578
+ new GoalCommitmentDefinition('GOAL'),
15579
+ new GoalCommitmentDefinition('GOALS'),
15580
+ new InitialMessageCommitmentDefinition(),
15581
+ new UserMessageCommitmentDefinition(),
15582
+ new AgentMessageCommitmentDefinition(),
15583
+ new MessageCommitmentDefinition('MESSAGE'),
15584
+ new MessageCommitmentDefinition('MESSAGES'),
15585
+ new ScenarioCommitmentDefinition('SCENARIO'),
15586
+ new ScenarioCommitmentDefinition('SCENARIOS'),
15587
+ new DeleteCommitmentDefinition('DELETE'),
15588
+ new DeleteCommitmentDefinition('CANCEL'),
15589
+ new DeleteCommitmentDefinition('DISCARD'),
15590
+ new DeleteCommitmentDefinition('REMOVE'),
15591
+ new DictionaryCommitmentDefinition(),
15592
+ new OpenCommitmentDefinition(),
15593
+ new ClosedCommitmentDefinition(),
15594
+ new UseBrowserCommitmentDefinition(),
15595
+ new UseSearchEngineCommitmentDefinition(),
15596
+ new UseTimeCommitmentDefinition(),
15597
+ new UseMcpCommitmentDefinition(),
15598
+ new UseCommitmentDefinition(),
15599
+ // Not yet implemented commitments (using placeholder)
15600
+ new NotYetImplementedCommitmentDefinition('EXPECT'),
15601
+ new NotYetImplementedCommitmentDefinition('BEHAVIOUR'),
15602
+ new NotYetImplementedCommitmentDefinition('BEHAVIOURS'),
15603
+ new NotYetImplementedCommitmentDefinition('AVOID'),
15604
+ new NotYetImplementedCommitmentDefinition('AVOIDANCE'),
15605
+ new NotYetImplementedCommitmentDefinition('CONTEXT'),
15606
+ ];
15607
+ /**
15608
+ * Gets all available commitment definitions
15609
+ * @returns Array of all commitment definitions
15610
+ *
15611
+ * @public exported from `@promptbook/core`
15612
+ */
15613
+ function getAllCommitmentDefinitions() {
15614
+ return $deepFreeze([...COMMITMENT_REGISTRY]);
15615
+ }
15616
+ /**
15617
+ * Gets all function implementations provided by all commitments
15618
+ *
15619
+ * @public exported from `@promptbook/core`
15620
+ */
15621
+ function getAllCommitmentsToolFunctions() {
15622
+ const allToolFunctions = {};
15623
+ for (const commitmentDefinition of getAllCommitmentDefinitions()) {
15624
+ const toolFunctions = commitmentDefinition.getToolFunctions();
15625
+ for (const [funcName, funcImpl] of Object.entries(toolFunctions)) {
15626
+ allToolFunctions[funcName] = funcImpl;
15627
+ }
15628
+ }
15629
+ return allToolFunctions;
15630
+ }
15631
+ /**
15632
+ * TODO: [🧠] Maybe create through standardized $register
15633
+ * Note: [💞] Ignore a discrepancy between file name and entity name
15634
+ */
15635
+
15636
+ /**
15637
+ * Extracts code block from markdown.
15638
+ *
15639
+ * - When there are multiple or no code blocks the function throws a `ParseError`
15640
+ *
15641
+ * Note: There are multiple similar function:
15642
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
15643
+ * - `extractJsonBlock` extracts exactly one valid JSON code block
15644
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
15645
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
15646
+ *
15647
+ * @public exported from `@promptbook/markdown-utils`
15648
+ * @throws {ParseError} if there is not exactly one code block in the markdown
15649
+ */
15650
+ function extractBlock(markdown) {
15651
+ const { content } = extractOneBlockFromMarkdown(markdown);
15652
+ return content;
15653
+ }
15654
+
15655
+ /**
15656
+ * Function trimCodeBlock will trim starting and ending code block from the string if it is present.
15657
+ *
15658
+ * Note: [🔂] This function is idempotent.
15659
+ * Note: This is useful for post-processing of the result of the chat LLM model
15660
+ * when the model wraps the result in the (markdown) code block.
15661
+ *
15662
+ * @public exported from `@promptbook/markdown-utils`
15663
+ */
15664
+ function trimCodeBlock(value) {
15665
+ value = spaceTrim$1.spaceTrim(value);
15666
+ if (!/^```[a-z]*(.*)```$/is.test(value)) {
15667
+ return value;
15668
+ }
15669
+ value = value.replace(/^```[a-z]*/i, '');
15670
+ value = value.replace(/```$/i, '');
15671
+ value = spaceTrim$1.spaceTrim(value);
15672
+ return value;
15673
+ }
15674
+
15675
+ /**
15676
+ * Function trimEndOfCodeBlock will remove ending code block from the string if it is present.
15677
+ *
15678
+ * Note: This is useful for post-processing of the result of the completion LLM model
15679
+ * if you want to start code block in the prompt but you don't want to end it in the result.
15680
+ *
15681
+ * @public exported from `@promptbook/markdown-utils`
15682
+ */
15683
+ function trimEndOfCodeBlock(value) {
15684
+ value = spaceTrim$1.spaceTrim(value);
15685
+ value = value.replace(/```$/g, '');
15686
+ value = spaceTrim$1.spaceTrim(value);
15687
+ return value;
15688
+ }
15689
+
15690
+ /**
15691
+ * @private internal for `preserve`
15692
+ */
15693
+ const _preserved = [];
15694
+ /**
15695
+ * Does nothing, but preserves the function in the bundle
15696
+ * Compiler is tricked into thinking the function is used
15697
+ *
15698
+ * @param value any function to preserve
15699
+ * @returns nothing
15700
+ * @private within the repository
15701
+ */
15702
+ function $preserve(...value) {
15703
+ _preserved.push(...value);
15704
+ }
15705
+ /**
15706
+ * Note: [💞] Ignore a discrepancy between file name and entity name
15707
+ */
15708
+
15709
+ // Note: [💎]
15710
+ /**
15711
+ * ScriptExecutionTools for JavaScript implemented via eval
15712
+ *
15713
+ * Warning: It is used for testing and mocking
15714
+ * **NOT intended to use in the production** due to its unsafe nature, use `JavascriptExecutionTools` instead.
15715
+ *
15716
+ * @public exported from `@promptbook/javascript`
15717
+ */
15718
+ class JavascriptEvalExecutionTools {
15719
+ constructor(options) {
15720
+ this.options = options || {};
15721
+ }
15722
+ /**
15723
+ * Executes a JavaScript
15724
+ */
15725
+ async execute(options) {
15726
+ const { scriptLanguage, parameters } = options;
15727
+ let { script } = options;
15728
+ if (scriptLanguage !== 'javascript') {
15729
+ throw new PipelineExecutionError(`Script language ${scriptLanguage} not supported to be executed by JavascriptEvalExecutionTools`);
15730
+ }
15731
+ // Note: [💎]
15732
+ // Note: Using direct eval, following variables are in same scope as eval call so they are accessible from inside the evaluated script:
15733
+ const spaceTrim = (_) => spaceTrim__default["default"](_);
15734
+ $preserve(spaceTrim);
15735
+ const removeQuotes$1 = removeQuotes;
15736
+ $preserve(removeQuotes$1);
15737
+ const unwrapResult$1 = unwrapResult;
15738
+ $preserve(unwrapResult$1);
15739
+ const trimEndOfCodeBlock$1 = trimEndOfCodeBlock;
15740
+ $preserve(trimEndOfCodeBlock$1);
15741
+ const trimCodeBlock$1 = trimCodeBlock;
15742
+ $preserve(trimCodeBlock$1);
15743
+ // TODO: DRY [🍯]
15744
+ const trim = (str) => str.trim();
15745
+ $preserve(trim);
15746
+ // TODO: DRY [🍯]
15747
+ const reverse = (str) => str.split('').reverse().join('');
12022
15748
  $preserve(reverse);
12023
15749
  const removeEmojis$1 = removeEmojis;
12024
15750
  $preserve(removeEmojis$1);
@@ -12087,6 +15813,13 @@
12087
15813
  `const ${functionName} = buildinFunctions.${functionName};`)
12088
15814
  .join('\n');
12089
15815
  // TODO: DRY [🍯]
15816
+ const commitmentsFunctions = getAllCommitmentsToolFunctions();
15817
+ const commitmentsFunctionsStatement = Object.keys(commitmentsFunctions)
15818
+ .map((functionName) =>
15819
+ // Note: Custom functions are exposed to the current scope as variables
15820
+ `const ${functionName} = commitmentsFunctions.${functionName};`)
15821
+ .join('\n');
15822
+ // TODO: DRY [🍯]
12090
15823
  const customFunctions = this.options.functions || {};
12091
15824
  const customFunctionsStatement = Object.keys(customFunctions)
12092
15825
  .map((functionName) =>
@@ -12100,6 +15833,10 @@
12100
15833
  // Build-in functions:
12101
15834
  ${block(buildinFunctionsStatement)}
12102
15835
 
15836
+ // Commitments functions:
15837
+ ${block(commitmentsFunctionsStatement)}
15838
+
15839
+
12103
15840
  // Custom functions:
12104
15841
  ${block(customFunctionsStatement || '// -- No custom functions --')}
12105
15842
 
@@ -12107,7 +15844,7 @@
12107
15844
  ${block(Object.entries(parameters)
12108
15845
  .map(([key, value]) => `const ${key} = ${JSON.stringify(value)};`)
12109
15846
  .join('\n'))}
12110
- (()=>{ ${script} })()
15847
+ (async ()=>{ ${script} })()
12111
15848
  `);
12112
15849
  if (this.options.isVerbose) {
12113
15850
  console.info(spaceTrim__default["default"]((block) => `