@promptbook/node 0.105.0-1 → 0.105.0-4

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