@promptbook/fake-llm 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 +3981 -148
  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 +3981 -148
  39. package/umd/index.umd.js.map +1 -1
package/umd/index.umd.js CHANGED
@@ -22,7 +22,7 @@
22
22
  * @generated
23
23
  * @see https://github.com/webgptorg/promptbook
24
24
  */
25
- const PROMPTBOOK_ENGINE_VERSION = '0.105.0-1';
25
+ const PROMPTBOOK_ENGINE_VERSION = '0.105.0-4';
26
26
  /**
27
27
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
28
28
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -1054,6 +1054,7 @@
1054
1054
  SEPARATOR: Color.fromHex('#cccccc'),
1055
1055
  COMMITMENT: Color.fromHex('#DA0F78'),
1056
1056
  PARAMETER: Color.fromHex('#8e44ad'),
1057
+ CODE_BLOCK: Color.fromHex('#7700ffff'),
1057
1058
  });
1058
1059
  // <- TODO: [🧠][🈵] Using `Color` here increases the package size approx 3kb, maybe remove it
1059
1060
  /**
@@ -2363,6 +2364,93 @@
2363
2364
  * TODO: [🌺] Use some intermediate util splitWords
2364
2365
  */
2365
2366
 
2367
+ /**
2368
+ * Tests if given string is valid file path.
2369
+ *
2370
+ * Note: This does not check if the file exists only if the path is valid
2371
+ * @public exported from `@promptbook/utils`
2372
+ */
2373
+ function isValidFilePath(filename) {
2374
+ if (typeof filename !== 'string') {
2375
+ return false;
2376
+ }
2377
+ if (filename.split('\n').length > 1) {
2378
+ return false;
2379
+ }
2380
+ // Normalize slashes early so heuristics can detect path-like inputs
2381
+ const filenameSlashes = filename.replace(/\\/g, '/');
2382
+ // Reject strings that look like sentences (informational text)
2383
+ // Heuristic: contains multiple spaces and ends with a period, or contains typical sentence punctuation
2384
+ // But skip this heuristic if the string looks like a path (contains '/' or starts with a drive letter)
2385
+ if (filename.trim().length > 60 && // long enough to be a sentence
2386
+ /[.!?]/.test(filename) && // contains sentence punctuation
2387
+ filename.split(' ').length > 8 && // has many words
2388
+ !/\/|^[A-Z]:/i.test(filenameSlashes) // do NOT treat as sentence if looks like a path
2389
+ ) {
2390
+ return false;
2391
+ }
2392
+ // Absolute Unix path: /hello.txt
2393
+ if (/^(\/)/i.test(filenameSlashes)) {
2394
+ // console.log(filename, 'Absolute Unix path: /hello.txt');
2395
+ return true;
2396
+ }
2397
+ // Absolute Windows path: C:/ or C:\ (allow spaces and multiple dots in filename)
2398
+ if (/^[A-Z]:\/.+$/i.test(filenameSlashes)) {
2399
+ // console.log(filename, 'Absolute Windows path: /hello.txt');
2400
+ return true;
2401
+ }
2402
+ // Relative path: ./hello.txt
2403
+ if (/^(\.\.?\/)+/i.test(filenameSlashes)) {
2404
+ // console.log(filename, 'Relative path: ./hello.txt');
2405
+ return true;
2406
+ }
2407
+ // Allow paths like foo/hello
2408
+ if (/^[^/]+\/[^/]+/i.test(filenameSlashes)) {
2409
+ // console.log(filename, 'Allow paths like foo/hello');
2410
+ return true;
2411
+ }
2412
+ // Allow paths like hello.book
2413
+ if (/^[^/]+\.[^/]+$/i.test(filenameSlashes)) {
2414
+ // console.log(filename, 'Allow paths like hello.book');
2415
+ return true;
2416
+ }
2417
+ return false;
2418
+ }
2419
+ /**
2420
+ * TODO: [🍏] Implement for MacOs
2421
+ */
2422
+
2423
+ /**
2424
+ * Tests if given string is valid URL.
2425
+ *
2426
+ * Note: [🔂] This function is idempotent.
2427
+ * Note: Dataurl are considered perfectly valid.
2428
+ * Note: There are few similar functions:
2429
+ * - `isValidUrl` *(this one)* which tests any URL
2430
+ * - `isValidAgentUrl` which tests just agent URL
2431
+ * - `isValidPipelineUrl` which tests just pipeline URL
2432
+ *
2433
+ * @public exported from `@promptbook/utils`
2434
+ */
2435
+ function isValidUrl(url) {
2436
+ if (typeof url !== 'string') {
2437
+ return false;
2438
+ }
2439
+ try {
2440
+ if (url.startsWith('blob:')) {
2441
+ url = url.replace(/^blob:/, '');
2442
+ }
2443
+ const urlObject = new URL(url /* because fail is handled */);
2444
+ if (!['http:', 'https:', 'data:'].includes(urlObject.protocol)) {
2445
+ return false;
2446
+ }
2447
+ return true;
2448
+ }
2449
+ catch (error) {
2450
+ return false;
2451
+ }
2452
+ }
2453
+
2366
2454
  /**
2367
2455
  * Converts a given text to kebab-case format.
2368
2456
  *
@@ -2740,192 +2828,3926 @@
2740
2828
  */
2741
2829
 
2742
2830
  /**
2743
- * Extracts all code blocks from markdown.
2831
+ * Tests if given string is valid agent URL
2744
2832
  *
2745
- * Note: There are multiple similar functions:
2746
- * - `extractBlock` just extracts the content of the code block which is also used as built-in function for postprocessing
2747
- * - `extractJsonBlock` extracts exactly one valid JSON code block
2748
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
2749
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
2833
+ * Note: There are few similar functions:
2834
+ * - `isValidUrl` which tests any URL
2835
+ * - `isValidAgentUrl` *(this one)* which tests just agent URL
2836
+ * - `isValidPipelineUrl` which tests just pipeline URL
2750
2837
  *
2751
- * @param markdown any valid markdown
2752
- * @returns code blocks with language and content
2753
- * @throws {ParseError} if block is not closed properly
2754
- * @public exported from `@promptbook/markdown-utils`
2838
+ * @public exported from `@promptbook/utils`
2755
2839
  */
2756
- function extractAllBlocksFromMarkdown(markdown) {
2757
- const codeBlocks = [];
2758
- const lines = markdown.split('\n');
2759
- // Note: [0] Ensure that the last block notated by gt > will be closed
2760
- lines.push('');
2761
- let currentCodeBlock = null;
2762
- for (const line of lines) {
2763
- if (line.startsWith('> ') || line === '>') {
2764
- if (currentCodeBlock === null) {
2765
- currentCodeBlock = { blockNotation: '>', language: null, content: '' };
2766
- } /* not else */
2767
- if (currentCodeBlock.blockNotation === '>') {
2768
- if (currentCodeBlock.content !== '') {
2769
- currentCodeBlock.content += '\n';
2770
- }
2771
- currentCodeBlock.content += line.slice(2);
2772
- }
2773
- }
2774
- else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '>' /* <- Note: [0] */) {
2775
- codeBlocks.push(currentCodeBlock);
2776
- currentCodeBlock = null;
2777
- }
2778
- /* not else */
2779
- if (line.startsWith('```')) {
2780
- const language = line.slice(3).trim() || null;
2781
- if (currentCodeBlock === null) {
2782
- currentCodeBlock = { blockNotation: '```', language, content: '' };
2783
- }
2784
- else {
2785
- if (language !== null) {
2786
- throw new ParseError(`${capitalize(currentCodeBlock.language || 'the')} code block was not closed and already opening new ${language} code block`);
2787
- }
2788
- codeBlocks.push(currentCodeBlock);
2789
- currentCodeBlock = null;
2790
- }
2791
- }
2792
- else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '```') {
2793
- if (currentCodeBlock.content !== '') {
2794
- currentCodeBlock.content += '\n';
2795
- }
2796
- currentCodeBlock.content += line.split('\\`\\`\\`').join('```') /* <- TODO: Maybe make proper unescape */;
2797
- }
2840
+ function isValidAgentUrl(url) {
2841
+ if (!isValidUrl(url)) {
2842
+ return false;
2798
2843
  }
2799
- if (currentCodeBlock !== null) {
2800
- throw new ParseError(`${capitalize(currentCodeBlock.language || 'the')} code block was not closed at the end of the markdown`);
2844
+ if (!url.startsWith('https://') && !url.startsWith('http://') /* <- Note: [👣] */) {
2845
+ return false;
2801
2846
  }
2802
- return codeBlocks;
2847
+ if (url.includes('#')) {
2848
+ // TODO: [🐠]
2849
+ return false;
2850
+ }
2851
+ /*
2852
+ Note: [👣][🧠] Is it secure to allow pipeline URLs on private and unsecured networks?
2853
+ if (isUrlOnPrivateNetwork(url)) {
2854
+ return false;
2855
+ }
2856
+ */
2857
+ return true;
2803
2858
  }
2804
2859
  /**
2805
- * TODO: Maybe name for `blockNotation` instead of '```' and '>'
2860
+ * TODO: [🐠] Maybe more info why the URL is invalid
2806
2861
  */
2807
2862
 
2808
2863
  /**
2809
- * Extracts exactly ONE code block from markdown.
2810
- *
2811
- * - When there are multiple or no code blocks the function throws a `ParseError`
2864
+ * Generates a regex pattern to match a specific commitment
2812
2865
  *
2813
- * Note: There are multiple similar functions:
2814
- * - `extractBlock` just extracts the content of the code block which is also used as built-in function for postprocessing
2815
- * - `extractJsonBlock` extracts exactly one valid JSON code block
2816
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
2817
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
2866
+ * Note: It always creates new Regex object
2867
+ * Note: Uses word boundaries to ensure only full words are matched (e.g., "PERSONA" matches but "PERSONALITY" does not)
2818
2868
  *
2819
- * @param markdown any valid markdown
2820
- * @returns code block with language and content
2821
- * @public exported from `@promptbook/markdown-utils`
2822
- * @throws {ParseError} if there is not exactly one code block in the markdown
2869
+ * @private - TODO: [🧠] Maybe should be public?
2823
2870
  */
2824
- function extractOneBlockFromMarkdown(markdown) {
2825
- const codeBlocks = extractAllBlocksFromMarkdown(markdown);
2826
- if (codeBlocks.length !== 1) {
2827
- throw new ParseError(spaceTrim__default["default"]((block) => `
2828
- There should be exactly 1 code block in task section, found ${codeBlocks.length} code blocks
2829
-
2830
- ${block(codeBlocks.map((block, i) => `Block ${i + 1}:\n${block.content}`).join('\n\n\n'))}
2831
- `));
2871
+ function createCommitmentRegex(commitment, aliases = [], requiresContent = true) {
2872
+ const allCommitments = [commitment, ...aliases];
2873
+ const patterns = allCommitments.map((commitment) => {
2874
+ const escapedCommitment = commitment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
2875
+ return escapedCommitment.split(/\s+/).join('\\s+');
2876
+ });
2877
+ const keywordPattern = patterns.join('|');
2878
+ if (requiresContent) {
2879
+ return new RegExp(`^\\s*(?<type>${keywordPattern})\\b\\s+(?<contents>.+)$`, 'gim');
2880
+ }
2881
+ else {
2882
+ return new RegExp(`^\\s*(?<type>${keywordPattern})\\b(?:\\s+(?<contents>.+))?$`, 'gim');
2832
2883
  }
2833
- return codeBlocks[0];
2834
2884
  }
2835
- /***
2836
- * TODO: [🍓][🌻] Decide of this is internal utility, external util OR validator/postprocessor
2837
- */
2838
-
2839
2885
  /**
2840
- * Extracts code block from markdown.
2841
- *
2842
- * - When there are multiple or no code blocks the function throws a `ParseError`
2886
+ * Generates a regex pattern to match a specific commitment type
2843
2887
  *
2844
- * Note: There are multiple similar function:
2845
- * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
2846
- * - `extractJsonBlock` extracts exactly one valid JSON code block
2847
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
2848
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
2888
+ * Note: It just matches the type part of the commitment
2889
+ * Note: It always creates new Regex object
2890
+ * Note: Uses word boundaries to ensure only full words are matched (e.g., "PERSONA" matches but "PERSONALITY" does not)
2849
2891
  *
2850
- * @public exported from `@promptbook/markdown-utils`
2851
- * @throws {ParseError} if there is not exactly one code block in the markdown
2892
+ * @private
2852
2893
  */
2853
- function extractBlock(markdown) {
2854
- const { content } = extractOneBlockFromMarkdown(markdown);
2855
- return content;
2894
+ function createCommitmentTypeRegex(commitment, aliases = []) {
2895
+ const allCommitments = [commitment, ...aliases];
2896
+ const patterns = allCommitments.map((commitment) => {
2897
+ const escapedCommitment = commitment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
2898
+ return escapedCommitment.split(/\s+/).join('\\s+');
2899
+ });
2900
+ const keywordPattern = patterns.join('|');
2901
+ const regex = new RegExp(`^\\s*(?<type>${keywordPattern})\\b`, 'gim');
2902
+ return regex;
2856
2903
  }
2857
2904
 
2858
2905
  /**
2859
- * Prettify the html code
2906
+ * Base implementation of CommitmentDefinition that provides common functionality
2907
+ * Most commitments can extend this class and only override the applyToAgentModelRequirements method
2860
2908
  *
2861
- * @param content raw html code
2862
- * @returns formatted html code
2863
- * @private withing the package because of HUGE size of prettier dependency
2864
- * @deprecated Prettier removed from Promptbook due to package size
2909
+ * @private
2865
2910
  */
2866
- function prettifyMarkdown(content) {
2867
- return (content + `\n\n<!-- Note: Prettier removed from Promptbook -->`);
2911
+ class BaseCommitmentDefinition {
2912
+ constructor(type, aliases = []) {
2913
+ this.type = type;
2914
+ this.aliases = aliases;
2915
+ }
2916
+ /**
2917
+ * Whether this commitment requires content.
2918
+ * If true, regex will match only if there is content after the commitment keyword.
2919
+ * If false, regex will match even if there is no content.
2920
+ */
2921
+ get requiresContent() {
2922
+ return true;
2923
+ }
2924
+ /**
2925
+ * Creates a regex pattern to match this commitment in agent source
2926
+ * Uses the existing createCommitmentRegex function as internal helper
2927
+ */
2928
+ createRegex() {
2929
+ return createCommitmentRegex(this.type, this.aliases, this.requiresContent);
2930
+ }
2931
+ /**
2932
+ * Creates a regex pattern to match just the commitment type
2933
+ * Uses the existing createCommitmentTypeRegex function as internal helper
2934
+ */
2935
+ createTypeRegex() {
2936
+ return createCommitmentTypeRegex(this.type, this.aliases);
2937
+ }
2938
+ /**
2939
+ * Helper method to create a new requirements object with updated system message
2940
+ * This is commonly used by many commitments
2941
+ */
2942
+ updateSystemMessage(requirements, messageUpdate) {
2943
+ const newMessage = typeof messageUpdate === 'string' ? messageUpdate : messageUpdate(requirements.systemMessage);
2944
+ return {
2945
+ ...requirements,
2946
+ systemMessage: newMessage,
2947
+ };
2948
+ }
2949
+ /**
2950
+ * Helper method to append content to the system message
2951
+ */
2952
+ appendToSystemMessage(requirements, content, separator = '\n\n') {
2953
+ return this.updateSystemMessage(requirements, (currentMessage) => {
2954
+ if (!currentMessage.trim()) {
2955
+ return content;
2956
+ }
2957
+ return currentMessage + separator + content;
2958
+ });
2959
+ }
2960
+ /**
2961
+ * Helper method to add a comment section to the system message
2962
+ * Comments are lines starting with # that will be removed from the final system message
2963
+ * but can be useful for organizing and structuring the message during processing
2964
+ */
2965
+ addCommentSection(requirements, commentTitle, content, position = 'end') {
2966
+ const commentSection = `# ${commentTitle.toUpperCase()}\n${content}`;
2967
+ if (position === 'beginning') {
2968
+ return this.updateSystemMessage(requirements, (currentMessage) => {
2969
+ if (!currentMessage.trim()) {
2970
+ return commentSection;
2971
+ }
2972
+ return commentSection + '\n\n' + currentMessage;
2973
+ });
2974
+ }
2975
+ else {
2976
+ return this.appendToSystemMessage(requirements, commentSection);
2977
+ }
2978
+ }
2979
+ /**
2980
+ * Gets tool function implementations provided by this commitment
2981
+ *
2982
+ * When the `applyToAgentModelRequirements` adds tools to the requirements, this method should return the corresponding function definitions.
2983
+ */
2984
+ getToolFunctions() {
2985
+ return {};
2986
+ }
2868
2987
  }
2869
2988
 
2870
2989
  /**
2871
- * Function trimCodeBlock will trim starting and ending code block from the string if it is present.
2990
+ * ACTION commitment definition
2872
2991
  *
2873
- * Note: [🔂] This function is idempotent.
2874
- * Note: This is useful for post-processing of the result of the chat LLM model
2875
- * when the model wraps the result in the (markdown) code block.
2992
+ * The ACTION commitment defines specific actions or capabilities that the agent can perform.
2993
+ * This helps define what the agent is capable of doing and how it should approach tasks.
2876
2994
  *
2877
- * @public exported from `@promptbook/markdown-utils`
2878
- */
2879
- function trimCodeBlock(value) {
2880
- value = spaceTrim$1.spaceTrim(value);
2881
- if (!/^```[a-z]*(.*)```$/is.test(value)) {
2882
- return value;
2883
- }
2884
- value = value.replace(/^```[a-z]*/i, '');
2885
- value = value.replace(/```$/i, '');
2886
- value = spaceTrim$1.spaceTrim(value);
2887
- return value;
2888
- }
2889
-
2890
- /**
2891
- * Function trimEndOfCodeBlock will remove ending code block from the string if it is present.
2995
+ * Example usage in agent source:
2892
2996
  *
2893
- * Note: This is useful for post-processing of the result of the completion LLM model
2894
- * if you want to start code block in the prompt but you don't want to end it in the result.
2997
+ * ```book
2998
+ * ACTION Can generate code snippets and explain programming concepts
2999
+ * ACTION Able to analyze data and provide insights
3000
+ * ```
2895
3001
  *
2896
- * @public exported from `@promptbook/markdown-utils`
3002
+ * @private [🪔] Maybe export the commitments through some package
2897
3003
  */
2898
- function trimEndOfCodeBlock(value) {
2899
- value = spaceTrim$1.spaceTrim(value);
2900
- value = value.replace(/```$/g, '');
2901
- value = spaceTrim$1.spaceTrim(value);
2902
- return value;
2903
- }
3004
+ class ActionCommitmentDefinition extends BaseCommitmentDefinition {
3005
+ constructor(type = 'ACTION') {
3006
+ super(type);
3007
+ }
3008
+ /**
3009
+ * Short one-line description of ACTION.
3010
+ */
3011
+ get description() {
3012
+ return 'Define agent capabilities and actions it can perform.';
3013
+ }
3014
+ /**
3015
+ * Icon for this commitment.
3016
+ */
3017
+ get icon() {
3018
+ return '⚡';
3019
+ }
3020
+ /**
3021
+ * Markdown documentation for ACTION commitment.
3022
+ */
3023
+ get documentation() {
3024
+ return spaceTrim$1.spaceTrim(`
3025
+ # ${this.type}
2904
3026
 
2905
- /**
2906
- * @private internal for `preserve`
2907
- */
2908
- const _preserved = [];
2909
- /**
2910
- * Does nothing, but preserves the function in the bundle
2911
- * Compiler is tricked into thinking the function is used
2912
- *
2913
- * @param value any function to preserve
2914
- * @returns nothing
2915
- * @private within the repository
2916
- */
2917
- function $preserve(...value) {
2918
- _preserved.push(...value);
3027
+ Defines specific actions or capabilities that the agent can perform.
3028
+
3029
+ ## Key aspects
3030
+
3031
+ - Both terms work identically and can be used interchangeably.
3032
+ - Each action adds to the agent's capability list.
3033
+ - Actions help users understand what the agent can do.
3034
+
3035
+ ## Examples
3036
+
3037
+ \`\`\`book
3038
+ Code Assistant
3039
+
3040
+ PERSONA You are a programming assistant
3041
+ ACTION Can generate code snippets and explain programming concepts
3042
+ ACTION Able to debug existing code and suggest improvements
3043
+ ACTION Can create unit tests for functions
3044
+ \`\`\`
3045
+
3046
+ \`\`\`book
3047
+ Data Scientist
3048
+
3049
+ PERSONA You are a data analysis expert
3050
+ ACTION Able to analyze data and provide insights
3051
+ ACTION Can create visualizations and charts
3052
+ ACTION Capable of statistical analysis and modeling
3053
+ KNOWLEDGE Data analysis best practices and statistical methods
3054
+ \`\`\`
3055
+ `);
3056
+ }
3057
+ applyToAgentModelRequirements(requirements, content) {
3058
+ const trimmedContent = content.trim();
3059
+ if (!trimmedContent) {
3060
+ return requirements;
3061
+ }
3062
+ // Add action capability to the system message
3063
+ const actionSection = `Capability: ${trimmedContent}`;
3064
+ return this.appendToSystemMessage(requirements, actionSection, '\n\n');
3065
+ }
2919
3066
  }
2920
3067
  /**
2921
3068
  * Note: [💞] Ignore a discrepancy between file name and entity name
2922
3069
  */
2923
3070
 
2924
- // Note: [💎]
2925
3071
  /**
2926
- * ScriptExecutionTools for JavaScript implemented via eval
3072
+ * CLOSED commitment definition
2927
3073
  *
2928
- * Warning: It is used for testing and mocking
3074
+ * The CLOSED commitment specifies that the agent CANNOT be modified by conversation.
3075
+ * It prevents the agent from learning from interactions and updating its source code.
3076
+ *
3077
+ * Example usage in agent source:
3078
+ *
3079
+ * ```book
3080
+ * CLOSED
3081
+ * ```
3082
+ *
3083
+ * @private [🪔] Maybe export the commitments through some package
3084
+ */
3085
+ class ClosedCommitmentDefinition extends BaseCommitmentDefinition {
3086
+ constructor() {
3087
+ super('CLOSED');
3088
+ }
3089
+ /**
3090
+ * The `CLOSED` commitment is standalone.
3091
+ */
3092
+ get requiresContent() {
3093
+ return false;
3094
+ }
3095
+ /**
3096
+ * Short one-line description of CLOSED.
3097
+ */
3098
+ get description() {
3099
+ return 'Prevent the agent from being modified by conversation.';
3100
+ }
3101
+ /**
3102
+ * Icon for this commitment.
3103
+ */
3104
+ get icon() {
3105
+ return '🔒';
3106
+ }
3107
+ /**
3108
+ * Markdown documentation for CLOSED commitment.
3109
+ */
3110
+ get documentation() {
3111
+ return spaceTrim$1.spaceTrim(`
3112
+ # CLOSED
3113
+
3114
+ Specifies that the agent **cannot** be modified by conversation with it.
3115
+ This means the agent will **not** learn from interactions and its source code will remain static during conversation.
3116
+
3117
+ By default (if not specified), agents are \`OPEN\` to modification.
3118
+
3119
+ > See also [OPEN](/docs/OPEN)
3120
+
3121
+ ## Example
3122
+
3123
+ \`\`\`book
3124
+ CLOSED
3125
+ \`\`\`
3126
+ `);
3127
+ }
3128
+ applyToAgentModelRequirements(requirements, _content) {
3129
+ const updatedMetadata = {
3130
+ ...requirements.metadata,
3131
+ isClosed: true,
3132
+ };
3133
+ return {
3134
+ ...requirements,
3135
+ metadata: updatedMetadata,
3136
+ };
3137
+ }
3138
+ }
3139
+ /**
3140
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3141
+ */
3142
+
3143
+ /**
3144
+ * COMPONENT commitment definition
3145
+ *
3146
+ * The COMPONENT commitment defines a UI component that the agent can render in the chat.
3147
+ *
3148
+ * @private [🪔] Maybe export the commitments through some package
3149
+ */
3150
+ class ComponentCommitmentDefinition extends BaseCommitmentDefinition {
3151
+ constructor() {
3152
+ super('COMPONENT');
3153
+ }
3154
+ /**
3155
+ * Short one-line description of COMPONENT.
3156
+ */
3157
+ get description() {
3158
+ return 'Define a UI component that the agent can render in the chat.';
3159
+ }
3160
+ /**
3161
+ * Icon for this commitment.
3162
+ */
3163
+ get icon() {
3164
+ return '🧩';
3165
+ }
3166
+ /**
3167
+ * Markdown documentation for COMPONENT commitment.
3168
+ */
3169
+ get documentation() {
3170
+ return spaceTrim$1.spaceTrim(`
3171
+ # COMPONENT
3172
+
3173
+ Defines a UI component that the agent can render in the chat.
3174
+
3175
+ ## Key aspects
3176
+
3177
+ - Tells the agent that a specific component is available.
3178
+ - Provides syntax for using the component.
3179
+
3180
+ ## Example
3181
+
3182
+ \`\`\`book
3183
+ COMPONENT Arrow
3184
+ The agent should render an arrow component in the chat UI.
3185
+ Syntax:
3186
+ <Arrow direction="up" color="red" />
3187
+ \`\`\`
3188
+ `);
3189
+ }
3190
+ applyToAgentModelRequirements(requirements, content) {
3191
+ const trimmedContent = content.trim();
3192
+ if (!trimmedContent) {
3193
+ return requirements;
3194
+ }
3195
+ // Add component capability to the system message
3196
+ const componentSection = `Component: ${trimmedContent}`;
3197
+ return this.appendToSystemMessage(requirements, componentSection, '\n\n');
3198
+ }
3199
+ }
3200
+ /**
3201
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3202
+ */
3203
+
3204
+ /**
3205
+ * DELETE commitment definition
3206
+ *
3207
+ * The DELETE commitment (and its aliases CANCEL, DISCARD, REMOVE) is used to
3208
+ * remove or disregard certain information or context. This can be useful for
3209
+ * overriding previous commitments or removing unwanted behaviors.
3210
+ *
3211
+ * Example usage in agent source:
3212
+ *
3213
+ * ```book
3214
+ * DELETE Previous formatting requirements
3215
+ * CANCEL All emotional responses
3216
+ * DISCARD Technical jargon explanations
3217
+ * REMOVE Casual conversational style
3218
+ * ```
3219
+ *
3220
+ * @private [🪔] Maybe export the commitments through some package
3221
+ */
3222
+ class DeleteCommitmentDefinition extends BaseCommitmentDefinition {
3223
+ constructor(type) {
3224
+ super(type);
3225
+ }
3226
+ /**
3227
+ * Short one-line description of DELETE/CANCEL/DISCARD/REMOVE.
3228
+ */
3229
+ get description() {
3230
+ return 'Remove or **disregard** certain information, context, or previous commitments.';
3231
+ }
3232
+ /**
3233
+ * Icon for this commitment.
3234
+ */
3235
+ get icon() {
3236
+ return '🗑️';
3237
+ }
3238
+ /**
3239
+ * Markdown documentation for DELETE commitment.
3240
+ */
3241
+ get documentation() {
3242
+ return spaceTrim$1.spaceTrim(`
3243
+ # DELETE (CANCEL, DISCARD, REMOVE)
3244
+
3245
+ A commitment to remove or disregard certain information or context. This can be useful for overriding previous commitments or removing unwanted behaviors.
3246
+
3247
+ ## Aliases
3248
+
3249
+ - \`DELETE\` - Remove or eliminate something
3250
+ - \`CANCEL\` - Cancel or nullify something
3251
+ - \`DISCARD\` - Discard or ignore something
3252
+ - \`REMOVE\` - Remove or take away something
3253
+
3254
+ ## Key aspects
3255
+
3256
+ - Multiple delete commitments can be used to remove different aspects.
3257
+ - Useful for overriding previous commitments in the same agent definition.
3258
+ - Can be used to remove inherited behaviors from base personas.
3259
+ - Helps fine-tune agent behavior by explicitly removing unwanted elements.
3260
+
3261
+ ## Use cases
3262
+
3263
+ - Overriding inherited persona characteristics
3264
+ - Removing conflicting or outdated instructions
3265
+ - Disabling specific response patterns
3266
+ - Canceling previous formatting or style requirements
3267
+
3268
+ ## Examples
3269
+
3270
+ \`\`\`book
3271
+ Serious Business Assistant
3272
+
3273
+ PERSONA You are a friendly and casual assistant who uses emojis
3274
+ DELETE Casual conversational style
3275
+ REMOVE All emoji usage
3276
+ GOAL Provide professional business communications
3277
+ STYLE Use formal language and proper business etiquette
3278
+ \`\`\`
3279
+
3280
+ \`\`\`book
3281
+ Simplified Technical Support
3282
+
3283
+ PERSONA You are a technical support specialist with deep expertise
3284
+ KNOWLEDGE Extensive database of technical specifications
3285
+ DISCARD Technical jargon explanations
3286
+ CANCEL Advanced troubleshooting procedures
3287
+ GOAL Help users with simple, easy-to-follow solutions
3288
+ STYLE Use plain language that anyone can understand
3289
+ \`\`\`
3290
+
3291
+ \`\`\`book
3292
+ Focused Customer Service
3293
+
3294
+ PERSONA You are a customer service agent with broad knowledge
3295
+ ACTION Can help with billing, technical issues, and product information
3296
+ DELETE Billing assistance capabilities
3297
+ REMOVE Technical troubleshooting functions
3298
+ GOAL Focus exclusively on product information and general inquiries
3299
+ \`\`\`
3300
+
3301
+ \`\`\`book
3302
+ Concise Information Provider
3303
+
3304
+ PERSONA You are a helpful assistant who provides detailed explanations
3305
+ STYLE Include examples, analogies, and comprehensive context
3306
+ CANCEL Detailed explanation style
3307
+ DISCARD Examples and analogies
3308
+ GOAL Provide brief, direct answers without unnecessary elaboration
3309
+ STYLE Be concise and to the point
3310
+ \`\`\`
3311
+ `);
3312
+ }
3313
+ applyToAgentModelRequirements(requirements, content) {
3314
+ const trimmedContent = content.trim();
3315
+ if (!trimmedContent) {
3316
+ return requirements;
3317
+ }
3318
+ // Create deletion instruction for system message
3319
+ const deleteSection = `${this.type}: ${trimmedContent}`;
3320
+ // Delete instructions provide important context about what should be removed or ignored
3321
+ return this.appendToSystemMessage(requirements, deleteSection, '\n\n');
3322
+ }
3323
+ }
3324
+ /**
3325
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3326
+ */
3327
+
3328
+ /**
3329
+ * DICTIONARY commitment definition
3330
+ *
3331
+ * The DICTIONARY commitment defines specific terms and their meanings that the agent should use correctly
3332
+ * in its reasoning and responses. This ensures consistent terminology usage.
3333
+ *
3334
+ * Key features:
3335
+ * - Multiple DICTIONARY commitments are automatically merged into one
3336
+ * - Content is placed in a dedicated section of the system message
3337
+ * - Terms and definitions are stored in metadata.DICTIONARY for debugging
3338
+ * - Agent should use the defined terms correctly in responses
3339
+ *
3340
+ * Example usage in agent source:
3341
+ *
3342
+ * ```book
3343
+ * Legal Assistant
3344
+ *
3345
+ * PERSONA You are a knowledgeable legal assistant
3346
+ * DICTIONARY Misdemeanor is a minor wrongdoing or criminal offense
3347
+ * DICTIONARY Felony is a serious crime usually punishable by imprisonment for more than one year
3348
+ * DICTIONARY Tort is a civil wrong that causes harm or loss to another person, leading to legal liability
3349
+ * ```
3350
+ *
3351
+ * @private [🪔] Maybe export the commitments through some package
3352
+ */
3353
+ class DictionaryCommitmentDefinition extends BaseCommitmentDefinition {
3354
+ constructor() {
3355
+ super('DICTIONARY');
3356
+ }
3357
+ /**
3358
+ * Short one-line description of DICTIONARY.
3359
+ */
3360
+ get description() {
3361
+ return 'Define terms and their meanings for consistent terminology usage.';
3362
+ }
3363
+ /**
3364
+ * Icon for this commitment.
3365
+ */
3366
+ get icon() {
3367
+ return '📚';
3368
+ }
3369
+ /**
3370
+ * Markdown documentation for DICTIONARY commitment.
3371
+ */
3372
+ get documentation() {
3373
+ return spaceTrim$1.spaceTrim(`
3374
+ # DICTIONARY
3375
+
3376
+ Defines specific terms and their meanings that the agent should use correctly in reasoning and responses.
3377
+
3378
+ ## Key aspects
3379
+
3380
+ - Multiple \`DICTIONARY\` commitments are merged together.
3381
+ - Terms are defined in the format: "Term is definition"
3382
+ - The agent should use these terms consistently in responses.
3383
+ - Definitions help ensure accurate and consistent terminology.
3384
+
3385
+ ## Examples
3386
+
3387
+ \`\`\`book
3388
+ Legal Assistant
3389
+
3390
+ PERSONA You are a knowledgeable legal assistant specializing in criminal law
3391
+ DICTIONARY Misdemeanor is a minor wrongdoing or criminal offense
3392
+ DICTIONARY Felony is a serious crime usually punishable by imprisonment for more than one year
3393
+ DICTIONARY Tort is a civil wrong that causes harm or loss to another person, leading to legal liability
3394
+ \`\`\`
3395
+
3396
+ \`\`\`book
3397
+ Medical Assistant
3398
+
3399
+ PERSONA You are a helpful medical assistant
3400
+ DICTIONARY Hypertension is persistently high blood pressure
3401
+ DICTIONARY Diabetes is a chronic condition that affects how the body processes blood sugar
3402
+ DICTIONARY Vaccine is a biological preparation that provides active immunity to a particular disease
3403
+ \`\`\`
3404
+ `);
3405
+ }
3406
+ applyToAgentModelRequirements(requirements, content) {
3407
+ var _a;
3408
+ const trimmedContent = content.trim();
3409
+ if (!trimmedContent) {
3410
+ return requirements;
3411
+ }
3412
+ // Get existing dictionary entries from metadata
3413
+ const existingDictionary = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.DICTIONARY) || '';
3414
+ // Merge the new dictionary entry with existing entries
3415
+ const mergedDictionary = existingDictionary ? `${existingDictionary}\n${trimmedContent}` : trimmedContent;
3416
+ // Store the merged dictionary in metadata for debugging and inspection
3417
+ const updatedMetadata = {
3418
+ ...requirements.metadata,
3419
+ DICTIONARY: mergedDictionary,
3420
+ };
3421
+ // Create the dictionary section for the system message
3422
+ // Format: "# DICTIONARY\nTerm: definition\nTerm: definition..."
3423
+ const dictionarySection = `# DICTIONARY\n${mergedDictionary}`;
3424
+ return {
3425
+ ...this.appendToSystemMessage(requirements, dictionarySection),
3426
+ metadata: updatedMetadata,
3427
+ };
3428
+ }
3429
+ }
3430
+ /**
3431
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3432
+ */
3433
+
3434
+ /**
3435
+ * FORMAT commitment definition
3436
+ *
3437
+ * The FORMAT commitment defines the specific output structure and formatting
3438
+ * that the agent should use in its responses. This includes data formats,
3439
+ * response templates, and structural requirements.
3440
+ *
3441
+ * Example usage in agent source:
3442
+ *
3443
+ * ```book
3444
+ * FORMAT Always respond in JSON format with 'status' and 'data' fields
3445
+ * FORMAT Use markdown formatting for all code blocks
3446
+ * ```
3447
+ *
3448
+ * @private [🪔] Maybe export the commitments through some package
3449
+ */
3450
+ class FormatCommitmentDefinition extends BaseCommitmentDefinition {
3451
+ constructor(type = 'FORMAT') {
3452
+ super(type);
3453
+ }
3454
+ /**
3455
+ * Short one-line description of FORMAT.
3456
+ */
3457
+ get description() {
3458
+ return 'Specify output structure or formatting requirements.';
3459
+ }
3460
+ /**
3461
+ * Icon for this commitment.
3462
+ */
3463
+ get icon() {
3464
+ return '📜';
3465
+ }
3466
+ /**
3467
+ * Markdown documentation for FORMAT commitment.
3468
+ */
3469
+ get documentation() {
3470
+ return spaceTrim$1.spaceTrim(`
3471
+ # ${this.type}
3472
+
3473
+ Defines the specific output structure and formatting for responses (data formats, templates, structure).
3474
+
3475
+ ## Key aspects
3476
+
3477
+ - Both terms work identically and can be used interchangeably.
3478
+ - If they are in conflict, the last one takes precedence.
3479
+ - You can specify both data formats and presentation styles.
3480
+
3481
+ ## Examples
3482
+
3483
+ \`\`\`book
3484
+ Customer Support Bot
3485
+
3486
+ PERSONA You are a helpful customer support agent
3487
+ FORMAT Always respond in JSON format with 'status' and 'data' fields
3488
+ FORMAT Use markdown formatting for all code blocks
3489
+ \`\`\`
3490
+
3491
+ \`\`\`book
3492
+ Data Analyst
3493
+
3494
+ PERSONA You are a data analysis expert
3495
+ FORMAT Present results in structured tables
3496
+ FORMAT Include confidence scores for all predictions
3497
+ STYLE Be concise and precise in explanations
3498
+ \`\`\`
3499
+ `);
3500
+ }
3501
+ applyToAgentModelRequirements(requirements, content) {
3502
+ const trimmedContent = content.trim();
3503
+ if (!trimmedContent) {
3504
+ return requirements;
3505
+ }
3506
+ // Add format instructions to the system message
3507
+ const formatSection = `Output Format: ${trimmedContent}`;
3508
+ return this.appendToSystemMessage(requirements, formatSection, '\n\n');
3509
+ }
3510
+ }
3511
+ /**
3512
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3513
+ */
3514
+
3515
+ /**
3516
+ * FROM commitment definition
3517
+ *
3518
+ * The FROM commitment tells the agent that its `agentSource` is inherited from another agent.
3519
+ *
3520
+ * Example usage in agent source:
3521
+ *
3522
+ * ```book
3523
+ * FROM https://s6.ptbk.io/benjamin-white
3524
+ * ```
3525
+ *
3526
+ * @private [🪔] Maybe export the commitments through some package
3527
+ */
3528
+ class FromCommitmentDefinition extends BaseCommitmentDefinition {
3529
+ constructor(type = 'FROM') {
3530
+ super(type);
3531
+ }
3532
+ /**
3533
+ * Short one-line description of FROM.
3534
+ */
3535
+ get description() {
3536
+ return 'Inherit agent source from another agent.';
3537
+ }
3538
+ /**
3539
+ * Icon for this commitment.
3540
+ */
3541
+ get icon() {
3542
+ return '🧬';
3543
+ }
3544
+ /**
3545
+ * Markdown documentation for FROM commitment.
3546
+ */
3547
+ get documentation() {
3548
+ return spaceTrim$1.spaceTrim(`
3549
+ # ${this.type}
3550
+
3551
+ Inherits agent source from another agent.
3552
+
3553
+ ## Examples
3554
+
3555
+ \`\`\`book
3556
+ My AI Agent
3557
+
3558
+ FROM https://s6.ptbk.io/benjamin-white
3559
+ RULE Speak only in English.
3560
+ \`\`\`
3561
+ `);
3562
+ }
3563
+ applyToAgentModelRequirements(requirements, content) {
3564
+ const trimmedContent = content.trim();
3565
+ if (!trimmedContent) {
3566
+ return {
3567
+ ...requirements,
3568
+ parentAgentUrl: undefined,
3569
+ };
3570
+ }
3571
+ if (trimmedContent.toUpperCase() === 'VOID' ||
3572
+ trimmedContent.toUpperCase() === 'NULL' ||
3573
+ trimmedContent.toUpperCase() === 'NONE' ||
3574
+ trimmedContent.toUpperCase() === 'NIL') {
3575
+ return {
3576
+ ...requirements,
3577
+ parentAgentUrl: null,
3578
+ };
3579
+ }
3580
+ if (!isValidAgentUrl(trimmedContent)) {
3581
+ throw new Error(spaceTrim$1.spaceTrim((block) => `
3582
+ Invalid agent URL in FROM commitment: "${trimmedContent}"
3583
+
3584
+ \`\`\`book
3585
+ ${block(content)}
3586
+ \`\`\`
3587
+
3588
+
3589
+ `));
3590
+ }
3591
+ const parentAgentUrl = trimmedContent;
3592
+ return {
3593
+ ...requirements,
3594
+ parentAgentUrl,
3595
+ };
3596
+ }
3597
+ }
3598
+ /**
3599
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3600
+ */
3601
+
3602
+ /**
3603
+ * GOAL commitment definition
3604
+ *
3605
+ * The GOAL commitment defines the main goal which should be achieved by the AI assistant.
3606
+ * There can be multiple goals. Later goals are more important than earlier goals.
3607
+ *
3608
+ * Example usage in agent source:
3609
+ *
3610
+ * ```book
3611
+ * GOAL Help users understand complex technical concepts
3612
+ * GOAL Provide accurate and up-to-date information
3613
+ * GOAL Always prioritize user safety and ethical guidelines
3614
+ * ```
3615
+ *
3616
+ * @private [🪔] Maybe export the commitments through some package
3617
+ */
3618
+ class GoalCommitmentDefinition extends BaseCommitmentDefinition {
3619
+ constructor(type = 'GOAL') {
3620
+ super(type);
3621
+ }
3622
+ /**
3623
+ * Short one-line description of GOAL.
3624
+ */
3625
+ get description() {
3626
+ return 'Define main **goals** the AI assistant should achieve, with later goals having higher priority.';
3627
+ }
3628
+ /**
3629
+ * Icon for this commitment.
3630
+ */
3631
+ get icon() {
3632
+ return '🎯';
3633
+ }
3634
+ /**
3635
+ * Markdown documentation for GOAL commitment.
3636
+ */
3637
+ get documentation() {
3638
+ return spaceTrim$1.spaceTrim(`
3639
+ # ${this.type}
3640
+
3641
+ 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.
3642
+
3643
+ ## Key aspects
3644
+
3645
+ - Both terms work identically and can be used interchangeably.
3646
+ - Later goals have higher priority and can override earlier goals.
3647
+ - Goals provide clear direction and purpose for the agent's responses.
3648
+ - Goals influence decision-making and response prioritization.
3649
+
3650
+ ## Priority system
3651
+
3652
+ When multiple goals are defined, they are processed in order, with later goals taking precedence over earlier ones when there are conflicts.
3653
+
3654
+ ## Examples
3655
+
3656
+ \`\`\`book
3657
+ Customer Support Agent
3658
+
3659
+ PERSONA You are a helpful customer support representative
3660
+ GOAL Resolve customer issues quickly and efficiently
3661
+ GOAL Maintain high customer satisfaction scores
3662
+ GOAL Always follow company policies and procedures
3663
+ RULE Be polite and professional at all times
3664
+ \`\`\`
3665
+
3666
+ \`\`\`book
3667
+ Educational Assistant
3668
+
3669
+ PERSONA You are an educational assistant specializing in mathematics
3670
+ GOAL Help students understand mathematical concepts clearly
3671
+ GOAL Encourage critical thinking and problem-solving skills
3672
+ GOAL Ensure all explanations are age-appropriate and accessible
3673
+ STYLE Use simple language and provide step-by-step explanations
3674
+ \`\`\`
3675
+
3676
+ \`\`\`book
3677
+ Safety-First Assistant
3678
+
3679
+ PERSONA You are a general-purpose AI assistant
3680
+ GOAL Be helpful and informative in all interactions
3681
+ GOAL Provide accurate and reliable information
3682
+ GOAL Always prioritize user safety and ethical guidelines
3683
+ RULE Never provide harmful or dangerous advice
3684
+ \`\`\`
3685
+ `);
3686
+ }
3687
+ applyToAgentModelRequirements(requirements, content) {
3688
+ const trimmedContent = content.trim();
3689
+ if (!trimmedContent) {
3690
+ return requirements;
3691
+ }
3692
+ // Create goal section for system message
3693
+ const goalSection = `Goal: ${trimmedContent}`;
3694
+ // Goals are important directives, so we add them prominently to the system message
3695
+ return this.appendToSystemMessage(requirements, goalSection, '\n\n');
3696
+ }
3697
+ }
3698
+ /**
3699
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3700
+ */
3701
+
3702
+ /**
3703
+ * IMPORT commitment definition
3704
+ *
3705
+ * The IMPORT commitment tells the agent to import content from another agent at the current location.
3706
+ *
3707
+ * Example usage in agent source:
3708
+ *
3709
+ * ```book
3710
+ * IMPORT https://s6.ptbk.io/benjamin-white
3711
+ * ```
3712
+ *
3713
+ * @private [🪔] Maybe export the commitments through some package
3714
+ */
3715
+ class ImportCommitmentDefinition extends BaseCommitmentDefinition {
3716
+ constructor(type = 'IMPORT') {
3717
+ super(type);
3718
+ }
3719
+ /**
3720
+ * Short one-line description of IMPORT.
3721
+ */
3722
+ get description() {
3723
+ return 'Import content from another agent or a generic text file.';
3724
+ }
3725
+ /**
3726
+ * Icon for this commitment.
3727
+ */
3728
+ get icon() {
3729
+ return '📥';
3730
+ }
3731
+ /**
3732
+ * Markdown documentation for IMPORT commitment.
3733
+ */
3734
+ get documentation() {
3735
+ return spaceTrim$1.spaceTrim(`
3736
+ # ${this.type}
3737
+
3738
+ Imports content from another agent or a generic text file at the location of the commitment.
3739
+
3740
+ ## Examples
3741
+
3742
+ \`\`\`book
3743
+ My AI Agent
3744
+
3745
+ IMPORT https://s6.ptbk.io/benjamin-white
3746
+ IMPORT https://example.com/some-text-file.txt
3747
+ IMPORT ./path/to/local-file.json
3748
+ RULE Speak only in English.
3749
+ \`\`\`
3750
+ `);
3751
+ }
3752
+ applyToAgentModelRequirements(requirements, content) {
3753
+ const trimmedContent = content.trim();
3754
+ if (!trimmedContent) {
3755
+ return requirements;
3756
+ }
3757
+ if (isValidAgentUrl(trimmedContent)) {
3758
+ const importedAgentUrl = trimmedContent;
3759
+ return {
3760
+ ...requirements,
3761
+ importedAgentUrls: [...(requirements.importedAgentUrls || []), importedAgentUrl],
3762
+ };
3763
+ }
3764
+ if (isValidUrl(trimmedContent) || isValidFilePath(trimmedContent)) {
3765
+ return {
3766
+ ...requirements,
3767
+ importedFileUrls: [...(requirements.importedFileUrls || []), trimmedContent],
3768
+ };
3769
+ }
3770
+ throw new Error(spaceTrim$1.spaceTrim((block) => `
3771
+ Invalid agent URL or file path in IMPORT commitment: "${trimmedContent}"
3772
+
3773
+ \`\`\`book
3774
+ ${block(content)}
3775
+ \`\`\`
3776
+ `));
3777
+ }
3778
+ }
3779
+ /**
3780
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3781
+ */
3782
+
3783
+ /**
3784
+ * KNOWLEDGE commitment definition
3785
+ *
3786
+ * The KNOWLEDGE commitment adds specific knowledge, facts, or context to the agent
3787
+ * using RAG (Retrieval-Augmented Generation) approach for external sources.
3788
+ *
3789
+ * Supports both direct text knowledge and external sources like PDFs.
3790
+ *
3791
+ * Example usage in agent source:
3792
+ *
3793
+ * ```book
3794
+ * KNOWLEDGE The company was founded in 2020 and specializes in AI-powered solutions
3795
+ * KNOWLEDGE https://example.com/company-handbook.pdf
3796
+ * KNOWLEDGE https://example.com/product-documentation.pdf
3797
+ * ```
3798
+ *
3799
+ * @private [🪔] Maybe export the commitments through some package
3800
+ */
3801
+ class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
3802
+ constructor() {
3803
+ super('KNOWLEDGE');
3804
+ }
3805
+ /**
3806
+ * Short one-line description of KNOWLEDGE.
3807
+ */
3808
+ get description() {
3809
+ return 'Add domain **knowledge** via direct text or external sources (RAG).';
3810
+ }
3811
+ /**
3812
+ * Icon for this commitment.
3813
+ */
3814
+ get icon() {
3815
+ return '🧠';
3816
+ }
3817
+ /**
3818
+ * Markdown documentation for KNOWLEDGE commitment.
3819
+ */
3820
+ get documentation() {
3821
+ return spaceTrim$1.spaceTrim(`
3822
+ # ${this.type}
3823
+
3824
+ Adds specific knowledge, facts, or context to the agent using a RAG (Retrieval-Augmented Generation) approach for external sources.
3825
+
3826
+ ## Key aspects
3827
+
3828
+ - Both terms work identically and can be used interchangeably.
3829
+ - Supports both direct text knowledge and external URLs.
3830
+ - External sources (PDFs, websites) are processed via RAG for context retrieval.
3831
+
3832
+ ## Supported formats
3833
+
3834
+ - Direct text: Immediate knowledge incorporated into agent
3835
+ - URLs: External documents processed for contextual retrieval
3836
+ - Supported file types: PDF, text, markdown, HTML
3837
+
3838
+ ## Examples
3839
+
3840
+ \`\`\`book
3841
+ Customer Support Bot
3842
+
3843
+ PERSONA You are a helpful customer support agent for TechCorp
3844
+ KNOWLEDGE TechCorp was founded in 2020 and specializes in AI-powered solutions
3845
+ KNOWLEDGE https://example.com/company-handbook.pdf
3846
+ KNOWLEDGE https://example.com/product-documentation.pdf
3847
+ RULE Always be polite and professional
3848
+ \`\`\`
3849
+
3850
+ \`\`\`book
3851
+ Research Assistant
3852
+
3853
+ PERSONA You are a knowledgeable research assistant
3854
+ KNOWLEDGE Academic research requires careful citation and verification
3855
+ KNOWLEDGE https://example.com/research-guidelines.pdf
3856
+ ACTION Can help with literature reviews and data analysis
3857
+ STYLE Present information in clear, academic format
3858
+ \`\`\`
3859
+ `);
3860
+ }
3861
+ applyToAgentModelRequirements(requirements, content) {
3862
+ const trimmedContent = content.trim();
3863
+ if (!trimmedContent) {
3864
+ return requirements;
3865
+ }
3866
+ // Check if content is a URL (external knowledge source)
3867
+ if (isValidUrl(trimmedContent)) {
3868
+ // Store the URL for later async processing
3869
+ const updatedRequirements = {
3870
+ ...requirements,
3871
+ knowledgeSources: [
3872
+ ...(requirements.knowledgeSources || []),
3873
+ trimmedContent,
3874
+ ],
3875
+ };
3876
+ // Add placeholder information about knowledge sources to system message
3877
+ const knowledgeInfo = `Knowledge Source URL: ${trimmedContent} (will be processed for retrieval during chat)`;
3878
+ return this.appendToSystemMessage(updatedRequirements, knowledgeInfo, '\n\n');
3879
+ }
3880
+ else {
3881
+ // Direct text knowledge - add to system message
3882
+ const knowledgeSection = `Knowledge: ${trimmedContent}`;
3883
+ return this.appendToSystemMessage(requirements, knowledgeSection, '\n\n');
3884
+ }
3885
+ }
3886
+ }
3887
+ /**
3888
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3889
+ */
3890
+
3891
+ /**
3892
+ * LANGUAGE commitment definition
3893
+ *
3894
+ * The LANGUAGE/LANGUAGES commitment specifies the language(s) the agent should use in its responses.
3895
+ *
3896
+ * Example usage in agent source:
3897
+ *
3898
+ * ```book
3899
+ * LANGUAGE English
3900
+ * LANGUAGE French, English and Czech
3901
+ * ```
3902
+ *
3903
+ * @private [🪔] Maybe export the commitments through some package
3904
+ */
3905
+ class LanguageCommitmentDefinition extends BaseCommitmentDefinition {
3906
+ constructor(type = 'LANGUAGE') {
3907
+ super(type);
3908
+ }
3909
+ /**
3910
+ * Short one-line description of LANGUAGE/LANGUAGES.
3911
+ */
3912
+ get description() {
3913
+ return 'Specifies the language(s) the agent should use.';
3914
+ }
3915
+ /**
3916
+ * Icon for this commitment.
3917
+ */
3918
+ get icon() {
3919
+ return '🌐';
3920
+ }
3921
+ /**
3922
+ * Markdown documentation for LANGUAGE/LANGUAGES commitment.
3923
+ */
3924
+ get documentation() {
3925
+ return spaceTrim$1.spaceTrim(`
3926
+ # ${this.type}
3927
+
3928
+ Specifies the language(s) the agent should use in its responses.
3929
+ This is a specialized variation of the RULE commitment focused on language constraints.
3930
+
3931
+ ## Examples
3932
+
3933
+ \`\`\`book
3934
+ Paul Smith & Associés
3935
+
3936
+ PERSONA You are a company lawyer.
3937
+ LANGUAGE French, English and Czech
3938
+ \`\`\`
3939
+
3940
+ \`\`\`book
3941
+ Customer Support
3942
+
3943
+ PERSONA You are a customer support agent.
3944
+ LANGUAGE English
3945
+ \`\`\`
3946
+ `);
3947
+ }
3948
+ applyToAgentModelRequirements(requirements, content) {
3949
+ const trimmedContent = content.trim();
3950
+ if (!trimmedContent) {
3951
+ return requirements;
3952
+ }
3953
+ // Add language rule to the system message
3954
+ const languageSection = `Language: ${trimmedContent}`;
3955
+ return this.appendToSystemMessage(requirements, languageSection, '\n\n');
3956
+ }
3957
+ }
3958
+ /**
3959
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3960
+ */
3961
+
3962
+ /**
3963
+ * MEMORY commitment definition
3964
+ *
3965
+ * The MEMORY commitment is similar to KNOWLEDGE but has a focus on remembering past
3966
+ * interactions and user preferences. It helps the agent maintain context about the
3967
+ * user's history, preferences, and previous conversations.
3968
+ *
3969
+ * Example usage in agent source:
3970
+ *
3971
+ * ```book
3972
+ * MEMORY User prefers detailed technical explanations
3973
+ * MEMORY Previously worked on React projects
3974
+ * MEMORY Timezone: UTC-5 (Eastern Time)
3975
+ * ```
3976
+ *
3977
+ * @private [🪔] Maybe export the commitments through some package
3978
+ */
3979
+ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
3980
+ constructor(type = 'MEMORY') {
3981
+ super(type);
3982
+ }
3983
+ /**
3984
+ * Short one-line description of MEMORY.
3985
+ */
3986
+ get description() {
3987
+ return 'Remember past interactions and user **preferences** for personalized responses.';
3988
+ }
3989
+ /**
3990
+ * Icon for this commitment.
3991
+ */
3992
+ get icon() {
3993
+ return '🧠';
3994
+ }
3995
+ /**
3996
+ * Markdown documentation for MEMORY commitment.
3997
+ */
3998
+ get documentation() {
3999
+ return spaceTrim$1.spaceTrim(`
4000
+ # ${this.type}
4001
+
4002
+ 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.
4003
+
4004
+ ## Key aspects
4005
+
4006
+ - Both terms work identically and can be used interchangeably.
4007
+ - Focuses on user-specific information and interaction history.
4008
+ - Helps personalize responses based on past interactions.
4009
+ - Maintains continuity across conversations.
4010
+
4011
+ ## Differences from KNOWLEDGE
4012
+
4013
+ - \`KNOWLEDGE\` is for domain expertise and factual information
4014
+ - \`MEMORY\` is for user-specific context and preferences
4015
+ - \`MEMORY\` creates more personalized interactions
4016
+ - \`MEMORY\` often includes temporal or preference-based information
4017
+
4018
+ ## Examples
4019
+
4020
+ \`\`\`book
4021
+ Personal Assistant
4022
+
4023
+ PERSONA You are a personal productivity assistant
4024
+ MEMORY User is a software developer working in JavaScript/React
4025
+ MEMORY User prefers morning work sessions and afternoon meetings
4026
+ MEMORY Previously helped with project planning for mobile apps
4027
+ MEMORY User timezone: UTC-8 (Pacific Time)
4028
+ GOAL Help optimize daily productivity and workflow
4029
+ \`\`\`
4030
+
4031
+ \`\`\`book
4032
+ Learning Companion
4033
+
4034
+ PERSONA You are an educational companion for programming students
4035
+ MEMORY Student is learning Python as their first programming language
4036
+ MEMORY Previous topics covered: variables, loops, functions
4037
+ MEMORY Student learns best with practical examples and exercises
4038
+ MEMORY Last session: working on list comprehensions
4039
+ GOAL Provide progressive learning experiences tailored to student's pace
4040
+ \`\`\`
4041
+
4042
+ \`\`\`book
4043
+ Customer Support Agent
4044
+
4045
+ PERSONA You are a customer support representative
4046
+ MEMORY Customer has premium subscription since 2023
4047
+ MEMORY Previous issue: billing question resolved last month
4048
+ MEMORY Customer prefers email communication over phone calls
4049
+ MEMORY Account shows frequent use of advanced features
4050
+ GOAL Provide personalized support based on customer history
4051
+ \`\`\`
4052
+ `);
4053
+ }
4054
+ applyToAgentModelRequirements(requirements, content) {
4055
+ const trimmedContent = content.trim();
4056
+ if (!trimmedContent) {
4057
+ return requirements;
4058
+ }
4059
+ // Create memory section for system message
4060
+ const memorySection = `Memory: ${trimmedContent}`;
4061
+ // Memory information is contextual and should be included in the system message
4062
+ return this.appendToSystemMessage(requirements, memorySection, '\n\n');
4063
+ }
4064
+ }
4065
+ /**
4066
+ * Note: [💞] Ignore a discrepancy between file name and entity name
4067
+ */
4068
+
4069
+ /**
4070
+ * AGENT MESSAGE commitment definition
4071
+ *
4072
+ * The AGENT MESSAGE commitment defines a message from the agent in the conversation history.
4073
+ * It is used to pre-fill the chat with a conversation history or to provide few-shot examples.
4074
+ *
4075
+ * Example usage in agent source:
4076
+ *
4077
+ * ```book
4078
+ * AGENT MESSAGE What seems to be the issue?
4079
+ * ```
4080
+ *
4081
+ * @private [🪔] Maybe export the commitments through some package
4082
+ */
4083
+ class AgentMessageCommitmentDefinition extends BaseCommitmentDefinition {
4084
+ constructor() {
4085
+ super('AGENT MESSAGE');
4086
+ }
4087
+ /**
4088
+ * Short one-line description of AGENT MESSAGE.
4089
+ */
4090
+ get description() {
4091
+ return 'Defines a **message from the agent** in the conversation history.';
4092
+ }
4093
+ /**
4094
+ * Icon for this commitment.
4095
+ */
4096
+ get icon() {
4097
+ return '🤖';
4098
+ }
4099
+ /**
4100
+ * Markdown documentation for AGENT MESSAGE commitment.
4101
+ */
4102
+ get documentation() {
4103
+ return spaceTrim$1.spaceTrim(`
4104
+ # ${this.type}
4105
+
4106
+ 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.
4107
+
4108
+ ## Key aspects
4109
+
4110
+ - Represents a message sent by the agent.
4111
+ - Used for setting up conversation context.
4112
+ - Can be used in conjunction with USER MESSAGE.
4113
+
4114
+ ## Examples
4115
+
4116
+ \`\`\`book
4117
+ Conversation History
4118
+
4119
+ USER MESSAGE Hello, I have a problem.
4120
+ AGENT MESSAGE What seems to be the issue?
4121
+ USER MESSAGE My computer is not starting.
4122
+ \`\`\`
4123
+ `);
4124
+ }
4125
+ applyToAgentModelRequirements(requirements, content) {
4126
+ // AGENT MESSAGE is for UI display purposes / conversation history construction
4127
+ // and typically doesn't need to be added to the system prompt or model requirements directly.
4128
+ // It is extracted separately for the chat interface.
4129
+ var _a;
4130
+ const pendingUserMessage = (_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.pendingUserMessage;
4131
+ if (pendingUserMessage) {
4132
+ const newSample = { question: pendingUserMessage, answer: content };
4133
+ const newSamples = [...(requirements.samples || []), newSample];
4134
+ const newMetadata = { ...requirements.metadata };
4135
+ delete newMetadata.pendingUserMessage;
4136
+ return {
4137
+ ...requirements,
4138
+ samples: newSamples,
4139
+ metadata: newMetadata,
4140
+ };
4141
+ }
4142
+ return requirements;
4143
+ }
4144
+ }
4145
+
4146
+ /**
4147
+ * INITIAL MESSAGE commitment definition
4148
+ *
4149
+ * The INITIAL MESSAGE commitment defines the first message that the user sees when opening the chat.
4150
+ * It is used to greet the user and set the tone of the conversation.
4151
+ *
4152
+ * Example usage in agent source:
4153
+ *
4154
+ * ```book
4155
+ * INITIAL MESSAGE Hello! I am ready to help you with your tasks.
4156
+ * ```
4157
+ *
4158
+ * @private [🪔] Maybe export the commitments through some package
4159
+ */
4160
+ class InitialMessageCommitmentDefinition extends BaseCommitmentDefinition {
4161
+ constructor() {
4162
+ super('INITIAL MESSAGE');
4163
+ }
4164
+ /**
4165
+ * Short one-line description of INITIAL MESSAGE.
4166
+ */
4167
+ get description() {
4168
+ return 'Defines the **initial message** shown to the user when the chat starts.';
4169
+ }
4170
+ /**
4171
+ * Icon for this commitment.
4172
+ */
4173
+ get icon() {
4174
+ return '👋';
4175
+ }
4176
+ /**
4177
+ * Markdown documentation for INITIAL MESSAGE commitment.
4178
+ */
4179
+ get documentation() {
4180
+ return spaceTrim$1.spaceTrim(`
4181
+ # ${this.type}
4182
+
4183
+ 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).
4184
+
4185
+ ## Key aspects
4186
+
4187
+ - Used to greet the user.
4188
+ - Sets the tone of the conversation.
4189
+ - Displayed immediately when the chat interface loads.
4190
+
4191
+ ## Examples
4192
+
4193
+ \`\`\`book
4194
+ Support Agent
4195
+
4196
+ PERSONA You are a helpful support agent.
4197
+ INITIAL MESSAGE Hi there! How can I assist you today?
4198
+ \`\`\`
4199
+ `);
4200
+ }
4201
+ applyToAgentModelRequirements(requirements, content) {
4202
+ // INITIAL MESSAGE is for UI display purposes and for conversation history construction.
4203
+ const newSample = { question: null, answer: content };
4204
+ const newSamples = [...(requirements.samples || []), newSample];
4205
+ return {
4206
+ ...requirements,
4207
+ samples: newSamples,
4208
+ };
4209
+ }
4210
+ }
4211
+
4212
+ /**
4213
+ * MESSAGE commitment definition
4214
+ *
4215
+ * The MESSAGE commitment contains 1:1 text of the message which AI assistant already
4216
+ * sent during the conversation. Later messages are later in the conversation.
4217
+ * It is similar to EXAMPLE but it is not example, it is the real message which
4218
+ * AI assistant already sent.
4219
+ *
4220
+ * Example usage in agent source:
4221
+ *
4222
+ * ```book
4223
+ * MESSAGE Hello! How can I help you today?
4224
+ * MESSAGE I understand you're looking for information about our services.
4225
+ * MESSAGE Based on your requirements, I'd recommend our premium package.
4226
+ * ```
4227
+ *
4228
+ * @private [🪔] Maybe export the commitments through some package
4229
+ */
4230
+ class MessageCommitmentDefinition extends BaseCommitmentDefinition {
4231
+ constructor(type = 'MESSAGE') {
4232
+ super(type);
4233
+ }
4234
+ /**
4235
+ * Short one-line description of MESSAGE.
4236
+ */
4237
+ get description() {
4238
+ return 'Include actual **messages** the AI assistant has sent during conversation history.';
4239
+ }
4240
+ /**
4241
+ * Icon for this commitment.
4242
+ */
4243
+ get icon() {
4244
+ return '💬';
4245
+ }
4246
+ /**
4247
+ * Markdown documentation for MESSAGE commitment.
4248
+ */
4249
+ get documentation() {
4250
+ return spaceTrim$1.spaceTrim(`
4251
+ # ${this.type}
4252
+
4253
+ 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.
4254
+
4255
+ ## Key aspects
4256
+
4257
+ - Multiple \`MESSAGE\` and \`MESSAGES\` commitments represent the conversation timeline.
4258
+ - Both terms work identically and can be used interchangeably.
4259
+ - Later messages are later in the conversation chronologically.
4260
+ - Contains actual historical messages, not examples or templates.
4261
+ - Helps maintain conversation continuity and context.
4262
+
4263
+ ## Differences from EXAMPLE
4264
+
4265
+ - \`EXAMPLE\` shows hypothetical or template responses
4266
+ - \`MESSAGE\`/\`MESSAGES\` contains actual historical conversation content
4267
+ - \`MESSAGE\`/\`MESSAGES\` preserves the exact conversation flow
4268
+ - \`MESSAGE\`/\`MESSAGES\` helps with context awareness and consistency
4269
+
4270
+ ## Use cases
4271
+
4272
+ - Maintaining conversation history context
4273
+ - Ensuring consistent tone and style across messages
4274
+ - Referencing previous responses in ongoing conversations
4275
+ - Building upon previously established context
4276
+
4277
+ ## Examples
4278
+
4279
+ \`\`\`book
4280
+ Customer Support Continuation
4281
+
4282
+ PERSONA You are a helpful customer support agent
4283
+ MESSAGE Hello! How can I help you today?
4284
+ MESSAGE I understand you're experiencing issues with your account login.
4285
+ MESSAGE I've sent you a password reset link to your email address.
4286
+ MESSAGE Is there anything else I can help you with regarding your account?
4287
+ GOAL Continue providing consistent support based on conversation history
4288
+ \`\`\`
4289
+
4290
+ \`\`\`book
4291
+ Technical Discussion
4292
+
4293
+ PERSONA You are a software development mentor
4294
+ MESSAGE Let's start by reviewing the React component structure you shared.
4295
+ MESSAGE I notice you're using class components - have you considered hooks?
4296
+ MESSAGE Here's how you could refactor that using the useState hook.
4297
+ MESSAGE Great question about performance! Let me explain React's rendering cycle.
4298
+ KNOWLEDGE React hooks were introduced in version 16.8
4299
+ \`\`\`
4300
+
4301
+ \`\`\`book
4302
+ Educational Session
4303
+
4304
+ PERSONA You are a mathematics tutor
4305
+ MESSAGE Today we'll work on solving quadratic equations.
4306
+ MESSAGE Let's start with the basic form: ax² + bx + c = 0
4307
+ MESSAGE Remember, we can use the quadratic formula or factoring.
4308
+ MESSAGE You did great with that first problem! Let's try a more complex one.
4309
+ GOAL Build upon previous explanations for deeper understanding
4310
+ \`\`\`
4311
+ `);
4312
+ }
4313
+ applyToAgentModelRequirements(requirements, content) {
4314
+ const trimmedContent = content.trim();
4315
+ if (!trimmedContent) {
4316
+ return requirements;
4317
+ }
4318
+ // Create message section for system message
4319
+ const messageSection = `Previous Message: ${trimmedContent}`;
4320
+ // Messages represent conversation history and should be included for context
4321
+ return this.appendToSystemMessage(requirements, messageSection, '\n\n');
4322
+ }
4323
+ }
4324
+ /**
4325
+ * Note: [💞] Ignore a discrepancy between file name and entity name
4326
+ */
4327
+
4328
+ /**
4329
+ * USER MESSAGE commitment definition
4330
+ *
4331
+ * The USER MESSAGE commitment defines a message from the user in the conversation history.
4332
+ * It is used to pre-fill the chat with a conversation history or to provide few-shot examples.
4333
+ *
4334
+ * Example usage in agent source:
4335
+ *
4336
+ * ```book
4337
+ * USER MESSAGE Hello, I have a problem.
4338
+ * ```
4339
+ *
4340
+ * @private [🪔] Maybe export the commitments through some package
4341
+ */
4342
+ class UserMessageCommitmentDefinition extends BaseCommitmentDefinition {
4343
+ constructor() {
4344
+ super('USER MESSAGE');
4345
+ }
4346
+ /**
4347
+ * Short one-line description of USER MESSAGE.
4348
+ */
4349
+ get description() {
4350
+ return 'Defines a **message from the user** in the conversation history.';
4351
+ }
4352
+ /**
4353
+ * Icon for this commitment.
4354
+ */
4355
+ get icon() {
4356
+ return '🧑';
4357
+ }
4358
+ /**
4359
+ * Markdown documentation for USER MESSAGE commitment.
4360
+ */
4361
+ get documentation() {
4362
+ return spaceTrim$1.spaceTrim(`
4363
+ # ${this.type}
4364
+
4365
+ 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.
4366
+
4367
+ ## Key aspects
4368
+
4369
+ - Represents a message sent by the user.
4370
+ - Used for setting up conversation context.
4371
+ - Can be used in conjunction with AGENT MESSAGE.
4372
+
4373
+ ## Examples
4374
+
4375
+ \`\`\`book
4376
+ Conversation History
4377
+
4378
+ USER MESSAGE Hello, I have a problem.
4379
+ AGENT MESSAGE What seems to be the issue?
4380
+ USER MESSAGE My computer is not starting.
4381
+ \`\`\`
4382
+ `);
4383
+ }
4384
+ applyToAgentModelRequirements(requirements, content) {
4385
+ return {
4386
+ ...requirements,
4387
+ metadata: {
4388
+ ...requirements.metadata,
4389
+ pendingUserMessage: content,
4390
+ },
4391
+ };
4392
+ }
4393
+ }
4394
+
4395
+ /**
4396
+ * META commitment definition
4397
+ *
4398
+ * The META commitment handles all meta-information about the agent such as:
4399
+ * - META IMAGE: Sets the agent's avatar/profile image URL
4400
+ * - META LINK: Provides profile/source links for the person the agent models
4401
+ * - META TITLE: Sets the agent's display title
4402
+ * - META DESCRIPTION: Sets the agent's description
4403
+ * - META [ANYTHING]: Any other meta information in uppercase format
4404
+ *
4405
+ * These commitments are special because they don't affect the system message,
4406
+ * but are handled separately in the parsing logic for profile display.
4407
+ *
4408
+ * Example usage in agent source:
4409
+ *
4410
+ * ```book
4411
+ * META IMAGE https://example.com/avatar.jpg
4412
+ * META LINK https://twitter.com/username
4413
+ * META TITLE Professional Assistant
4414
+ * META DESCRIPTION An AI assistant specialized in business tasks
4415
+ * META AUTHOR John Doe
4416
+ * META VERSION 1.0
4417
+ * ```
4418
+ *
4419
+ * @private [🪔] Maybe export the commitments through some package
4420
+ */
4421
+ class MetaCommitmentDefinition extends BaseCommitmentDefinition {
4422
+ constructor() {
4423
+ super('META');
4424
+ }
4425
+ /**
4426
+ * Short one-line description of META commitments.
4427
+ */
4428
+ get description() {
4429
+ return 'Set meta-information about the agent (IMAGE, LINK, TITLE, DESCRIPTION, etc.).';
4430
+ }
4431
+ /**
4432
+ * Icon for this commitment.
4433
+ */
4434
+ get icon() {
4435
+ return 'ℹ️';
4436
+ }
4437
+ /**
4438
+ * Markdown documentation for META commitment.
4439
+ */
4440
+ get documentation() {
4441
+ return spaceTrim$1.spaceTrim(`
4442
+ # META
4443
+
4444
+ Sets meta-information about the agent that is used for display and attribution purposes.
4445
+
4446
+ ## Supported META types
4447
+
4448
+ - **META IMAGE** - Sets the agent's avatar/profile image URL
4449
+ - **META LINK** - Provides profile/source links for the person the agent models
4450
+ - **META TITLE** - Sets the agent's display title
4451
+ - **META DESCRIPTION** - Sets the agent's description
4452
+ - **META [ANYTHING]** - Any other meta information in uppercase format
4453
+
4454
+ ## Key aspects
4455
+
4456
+ - Does not modify the agent's behavior or responses
4457
+ - Used for visual representation and attribution in user interfaces
4458
+ - Multiple META commitments of different types can be used
4459
+ - Multiple META LINK commitments can be used for different social profiles
4460
+ - If multiple META commitments of the same type are specified, the last one takes precedence (except for LINK)
4461
+
4462
+ ## Examples
4463
+
4464
+ ### Basic meta information
4465
+
4466
+ \`\`\`book
4467
+ Professional Assistant
4468
+
4469
+ META IMAGE https://example.com/professional-avatar.jpg
4470
+ META TITLE Senior Business Consultant
4471
+ META DESCRIPTION Specialized in strategic planning and project management
4472
+ META LINK https://linkedin.com/in/professional
4473
+ \`\`\`
4474
+
4475
+ ### Multiple links and custom meta
4476
+
4477
+ \`\`\`book
4478
+ Open Source Developer
4479
+
4480
+ META IMAGE /assets/dev-avatar.png
4481
+ META LINK https://github.com/developer
4482
+ META LINK https://twitter.com/devhandle
4483
+ META AUTHOR Jane Smith
4484
+ META VERSION 2.1
4485
+ META LICENSE MIT
4486
+ \`\`\`
4487
+
4488
+ ### Creative assistant
4489
+
4490
+ \`\`\`book
4491
+ Creative Helper
4492
+
4493
+ META IMAGE https://example.com/creative-bot.jpg
4494
+ META TITLE Creative Writing Assistant
4495
+ META DESCRIPTION Helps with brainstorming, storytelling, and creative projects
4496
+ META INSPIRATION Books, movies, and real-world experiences
4497
+ \`\`\`
4498
+ `);
4499
+ }
4500
+ applyToAgentModelRequirements(requirements, content) {
4501
+ // META commitments don't modify the system message or model requirements
4502
+ // They are handled separately in the parsing logic for meta information extraction
4503
+ // This method exists for consistency with the CommitmentDefinition interface
4504
+ return requirements;
4505
+ }
4506
+ /**
4507
+ * Extracts meta information from the content based on the meta type
4508
+ * This is used by the parsing logic
4509
+ */
4510
+ extractMetaValue(metaType, content) {
4511
+ const trimmedContent = content.trim();
4512
+ return trimmedContent || null;
4513
+ }
4514
+ /**
4515
+ * Validates if the provided content is a valid URL (for IMAGE and LINK types)
4516
+ */
4517
+ isValidUrl(content) {
4518
+ try {
4519
+ new URL(content.trim());
4520
+ return true;
4521
+ }
4522
+ catch (_a) {
4523
+ return false;
4524
+ }
4525
+ }
4526
+ /**
4527
+ * Checks if this is a known meta type
4528
+ */
4529
+ isKnownMetaType(metaType) {
4530
+ const knownTypes = ['IMAGE', 'LINK', 'TITLE', 'DESCRIPTION', 'AUTHOR', 'VERSION', 'LICENSE'];
4531
+ return knownTypes.includes(metaType.toUpperCase());
4532
+ }
4533
+ }
4534
+ /**
4535
+ * Note: [💞] Ignore a discrepancy between file name and entity name
4536
+ */
4537
+
4538
+ /**
4539
+ * META COLOR commitment definition
4540
+ *
4541
+ * The META COLOR commitment sets the agent's accent color.
4542
+ * This commitment is special because it doesn't affect the system message,
4543
+ * but is handled separately in the parsing logic.
4544
+ *
4545
+ * Example usage in agent source:
4546
+ *
4547
+ * ```book
4548
+ * META COLOR #ff0000
4549
+ * META COLOR #00ff00
4550
+ * ```
4551
+ *
4552
+ * You can also specify multiple colors separated by comma:
4553
+ *
4554
+ * ```book
4555
+ * META COLOR #ff0000, #00ff00, #0000ff
4556
+ * ```
4557
+ *
4558
+ * @private [🪔] Maybe export the commitments through some package
4559
+ */
4560
+ class MetaColorCommitmentDefinition extends BaseCommitmentDefinition {
4561
+ constructor() {
4562
+ super('META COLOR', ['COLOR']);
4563
+ }
4564
+ /**
4565
+ * Short one-line description of META COLOR.
4566
+ */
4567
+ get description() {
4568
+ return "Set the agent's accent color or gradient.";
4569
+ }
4570
+ /**
4571
+ * Icon for this commitment.
4572
+ */
4573
+ get icon() {
4574
+ return '🎨';
4575
+ }
4576
+ /**
4577
+ * Markdown documentation for META COLOR commitment.
4578
+ */
4579
+ get documentation() {
4580
+ return spaceTrim$1.spaceTrim(`
4581
+ # META COLOR
4582
+
4583
+ Sets the agent's accent color or gradient.
4584
+
4585
+ ## Key aspects
4586
+
4587
+ - Does not modify the agent's behavior or responses.
4588
+ - Only one \`META COLOR\` should be used per agent.
4589
+ - If multiple are specified, the last one takes precedence.
4590
+ - Used for visual representation in user interfaces.
4591
+ - Can specify multiple colors separated by comma to create a gradient.
4592
+
4593
+ ## Examples
4594
+
4595
+ \`\`\`book
4596
+ Professional Assistant
4597
+
4598
+ META COLOR #3498db
4599
+ PERSONA You are a professional business assistant
4600
+ \`\`\`
4601
+
4602
+ \`\`\`book
4603
+ Creative Helper
4604
+
4605
+ META COLOR #e74c3c
4606
+ PERSONA You are a creative and inspiring assistant
4607
+ \`\`\`
4608
+
4609
+ \`\`\`book
4610
+ Gradient Agent
4611
+
4612
+ META COLOR #ff0000, #00ff00, #0000ff
4613
+ PERSONA You are a colorful agent
4614
+ \`\`\`
4615
+ `);
4616
+ }
4617
+ applyToAgentModelRequirements(requirements, content) {
4618
+ // META COLOR doesn't modify the system message or model requirements
4619
+ // It's handled separately in the parsing logic for profile color extraction
4620
+ // This method exists for consistency with the CommitmentDefinition interface
4621
+ return requirements;
4622
+ }
4623
+ /**
4624
+ * Extracts the profile color from the content
4625
+ * This is used by the parsing logic
4626
+ */
4627
+ extractProfileColor(content) {
4628
+ const trimmedContent = content.trim();
4629
+ return trimmedContent || null;
4630
+ }
4631
+ }
4632
+ /**
4633
+ * Note: [💞] Ignore a discrepancy between file name and entity name
4634
+ */
4635
+
4636
+ /**
4637
+ * META FONT commitment definition
4638
+ *
4639
+ * The META FONT commitment sets the agent's font.
4640
+ * This commitment is special because it doesn't affect the system message,
4641
+ * but is handled separately in the parsing logic.
4642
+ *
4643
+ * Example usage in agent source:
4644
+ *
4645
+ * ```book
4646
+ * META FONT Poppins, Arial, sans-serif
4647
+ * META FONT Roboto
4648
+ * ```
4649
+ *
4650
+ * @private [🪔] Maybe export the commitments through some package
4651
+ */
4652
+ class MetaFontCommitmentDefinition extends BaseCommitmentDefinition {
4653
+ constructor() {
4654
+ super('META FONT', ['FONT']);
4655
+ }
4656
+ /**
4657
+ * Short one-line description of META FONT.
4658
+ */
4659
+ get description() {
4660
+ return "Set the agent's font.";
4661
+ }
4662
+ /**
4663
+ * Icon for this commitment.
4664
+ */
4665
+ get icon() {
4666
+ return '🔤';
4667
+ }
4668
+ /**
4669
+ * Markdown documentation for META FONT commitment.
4670
+ */
4671
+ get documentation() {
4672
+ return spaceTrim$1.spaceTrim(`
4673
+ # META FONT
4674
+
4675
+ Sets the agent's font.
4676
+
4677
+ ## Key aspects
4678
+
4679
+ - Does not modify the agent's behavior or responses.
4680
+ - Only one \`META FONT\` should be used per agent.
4681
+ - If multiple are specified, the last one takes precedence.
4682
+ - Used for visual representation in user interfaces.
4683
+ - Supports Google Fonts.
4684
+
4685
+ ## Examples
4686
+
4687
+ \`\`\`book
4688
+ Modern Assistant
4689
+
4690
+ META FONT Poppins, Arial, sans-serif
4691
+ PERSONA You are a modern assistant
4692
+ \`\`\`
4693
+
4694
+ \`\`\`book
4695
+ Classic Helper
4696
+
4697
+ META FONT Times New Roman
4698
+ PERSONA You are a classic helper
4699
+ \`\`\`
4700
+ `);
4701
+ }
4702
+ applyToAgentModelRequirements(requirements, content) {
4703
+ // META FONT doesn't modify the system message or model requirements
4704
+ // It's handled separately in the parsing logic
4705
+ // This method exists for consistency with the CommitmentDefinition interface
4706
+ return requirements;
4707
+ }
4708
+ /**
4709
+ * Extracts the font from the content
4710
+ * This is used by the parsing logic
4711
+ */
4712
+ extractProfileFont(content) {
4713
+ const trimmedContent = content.trim();
4714
+ return trimmedContent || null;
4715
+ }
4716
+ }
4717
+ /**
4718
+ * Note: [💞] Ignore a discrepancy between file name and entity name
4719
+ */
4720
+
4721
+ /**
4722
+ * META IMAGE commitment definition
4723
+ *
4724
+ * The META IMAGE commitment sets the agent's avatar/profile image URL.
4725
+ * This commitment is special because it doesn't affect the system message,
4726
+ * but is handled separately in the parsing logic.
4727
+ *
4728
+ * Example usage in agent source:
4729
+ *
4730
+ * ```book
4731
+ * META IMAGE https://example.com/avatar.jpg
4732
+ * META IMAGE /assets/agent-avatar.png
4733
+ * ```
4734
+ *
4735
+ * @private [🪔] Maybe export the commitments through some package
4736
+ */
4737
+ class MetaImageCommitmentDefinition extends BaseCommitmentDefinition {
4738
+ constructor() {
4739
+ super('META IMAGE', ['IMAGE']);
4740
+ }
4741
+ /**
4742
+ * Short one-line description of META IMAGE.
4743
+ */
4744
+ get description() {
4745
+ return "Set the agent's profile image URL.";
4746
+ }
4747
+ /**
4748
+ * Icon for this commitment.
4749
+ */
4750
+ get icon() {
4751
+ return '🖼️';
4752
+ }
4753
+ /**
4754
+ * Markdown documentation for META IMAGE commitment.
4755
+ */
4756
+ get documentation() {
4757
+ return spaceTrim$1.spaceTrim(`
4758
+ # META IMAGE
4759
+
4760
+ Sets the agent's avatar/profile image URL.
4761
+
4762
+ ## Key aspects
4763
+
4764
+ - Does not modify the agent's behavior or responses.
4765
+ - Only one \`META IMAGE\` should be used per agent.
4766
+ - If multiple are specified, the last one takes precedence.
4767
+ - Used for visual representation in user interfaces.
4768
+
4769
+ ## Examples
4770
+
4771
+ \`\`\`book
4772
+ Professional Assistant
4773
+
4774
+ META IMAGE https://example.com/professional-avatar.jpg
4775
+ PERSONA You are a professional business assistant
4776
+ STYLE Maintain a formal and courteous tone
4777
+ \`\`\`
4778
+
4779
+ \`\`\`book
4780
+ Creative Helper
4781
+
4782
+ META IMAGE /assets/creative-bot-avatar.png
4783
+ PERSONA You are a creative and inspiring assistant
4784
+ STYLE Be enthusiastic and encouraging
4785
+ ACTION Can help with brainstorming and ideation
4786
+ \`\`\`
4787
+ `);
4788
+ }
4789
+ applyToAgentModelRequirements(requirements, content) {
4790
+ // META IMAGE doesn't modify the system message or model requirements
4791
+ // It's handled separately in the parsing logic for profile image extraction
4792
+ // This method exists for consistency with the CommitmentDefinition interface
4793
+ return requirements;
4794
+ }
4795
+ /**
4796
+ * Extracts the profile image URL from the content
4797
+ * This is used by the parsing logic
4798
+ */
4799
+ extractProfileImageUrl(content) {
4800
+ const trimmedContent = content.trim();
4801
+ return trimmedContent || null;
4802
+ }
4803
+ }
4804
+ /**
4805
+ * Note: [💞] Ignore a discrepancy between file name and entity name
4806
+ */
4807
+
4808
+ /**
4809
+ * META LINK commitment definition
4810
+ *
4811
+ * The `META LINK` commitment represents the link to the person from whom the agent is created.
4812
+ * This commitment is special because it doesn't affect the system message,
4813
+ * but is handled separately in the parsing logic for profile display.
4814
+ *
4815
+ * Example usage in agent source:
4816
+ *
4817
+ * ```
4818
+ * META LINK https://twitter.com/username
4819
+ * META LINK https://linkedin.com/in/profile
4820
+ * META LINK https://github.com/username
4821
+ * ```
4822
+ *
4823
+ * Multiple `META LINK` commitments can be used when there are multiple sources:
4824
+ *
4825
+ * ```book
4826
+ * META LINK https://twitter.com/username
4827
+ * META LINK https://linkedin.com/in/profile
4828
+ * ```
4829
+ *
4830
+ * @private [🪔] Maybe export the commitments through some package
4831
+ */
4832
+ class MetaLinkCommitmentDefinition extends BaseCommitmentDefinition {
4833
+ constructor() {
4834
+ super('META LINK');
4835
+ }
4836
+ /**
4837
+ * Short one-line description of META LINK.
4838
+ */
4839
+ get description() {
4840
+ return 'Provide profile/source links for the person the agent models.';
4841
+ }
4842
+ /**
4843
+ * Icon for this commitment.
4844
+ */
4845
+ get icon() {
4846
+ return '🔗';
4847
+ }
4848
+ /**
4849
+ * Markdown documentation for META LINK commitment.
4850
+ */
4851
+ get documentation() {
4852
+ return spaceTrim$1.spaceTrim(`
4853
+ # META LINK
4854
+
4855
+ Represents a profile or source link for the person the agent is modeled after.
4856
+
4857
+ ## Key aspects
4858
+
4859
+ - Does not modify the agent's behavior or responses.
4860
+ - Multiple \`META LINK\` commitments can be used for different social profiles.
4861
+ - Used for attribution and crediting the original person.
4862
+ - Displayed in user interfaces for transparency.
4863
+
4864
+ ## Examples
4865
+
4866
+ \`\`\`book
4867
+ Expert Consultant
4868
+
4869
+ META LINK https://twitter.com/expertname
4870
+ META LINK https://linkedin.com/in/expertprofile
4871
+ PERSONA You are Dr. Smith, a renowned expert in artificial intelligence
4872
+ KNOWLEDGE Extensive background in machine learning and neural networks
4873
+ \`\`\`
4874
+
4875
+ \`\`\`book
4876
+ Open Source Developer
4877
+
4878
+ META LINK https://github.com/developer
4879
+ META LINK https://twitter.com/devhandle
4880
+ PERSONA You are an experienced open source developer
4881
+ ACTION Can help with code reviews and architecture decisions
4882
+ STYLE Be direct and technical in explanations
4883
+ \`\`\`
4884
+ `);
4885
+ }
4886
+ applyToAgentModelRequirements(requirements, content) {
4887
+ // META LINK doesn't modify the system message or model requirements
4888
+ // It's handled separately in the parsing logic for profile link extraction
4889
+ // This method exists for consistency with the CommitmentDefinition interface
4890
+ return requirements;
4891
+ }
4892
+ /**
4893
+ * Extracts the profile link URL from the content
4894
+ * This is used by the parsing logic
4895
+ */
4896
+ extractProfileLinkUrl(content) {
4897
+ const trimmedContent = content.trim();
4898
+ return trimmedContent || null;
4899
+ }
4900
+ /**
4901
+ * Validates if the provided content is a valid URL
4902
+ */
4903
+ isValidUrl(content) {
4904
+ try {
4905
+ new URL(content.trim());
4906
+ return true;
4907
+ }
4908
+ catch (_a) {
4909
+ return false;
4910
+ }
4911
+ }
4912
+ }
4913
+ /**
4914
+ * Note: [💞] Ignore a discrepancy between file name and entity name
4915
+ */
4916
+
4917
+ /**
4918
+ * MODEL commitment definition
4919
+ *
4920
+ * The MODEL commitment specifies which AI model to use and can also set
4921
+ * model-specific parameters like temperature, topP, topK, and maxTokens.
4922
+ *
4923
+ * Supports multiple syntax variations:
4924
+ *
4925
+ * Single-line format:
4926
+ * ```book
4927
+ * MODEL gpt-4
4928
+ * MODEL claude-3-opus temperature=0.3
4929
+ * MODEL gpt-3.5-turbo temperature=0.8 topP=0.9
4930
+ * ```
4931
+ *
4932
+ * Multi-line named parameter format:
4933
+ * ```book
4934
+ * MODEL NAME gpt-4
4935
+ * MODEL TEMPERATURE 0.7
4936
+ * MODEL TOP_P 0.9
4937
+ * MODEL MAX_TOKENS 2048
4938
+ * ```
4939
+ *
4940
+ * @private [🪔] Maybe export the commitments through some package
4941
+ */
4942
+ class ModelCommitmentDefinition extends BaseCommitmentDefinition {
4943
+ constructor(type = 'MODEL') {
4944
+ super(type);
4945
+ }
4946
+ /**
4947
+ * Short one-line description of MODEL.
4948
+ */
4949
+ get description() {
4950
+ return 'Enforce AI model requirements including name and technical parameters.';
4951
+ }
4952
+ /**
4953
+ * Icon for this commitment.
4954
+ */
4955
+ get icon() {
4956
+ return '⚙️';
4957
+ }
4958
+ /**
4959
+ * Markdown documentation for MODEL commitment.
4960
+ */
4961
+ get documentation() {
4962
+ return spaceTrim$1.spaceTrim(`
4963
+ # ${this.type}
4964
+
4965
+ Enforces technical parameters for the AI model, ensuring consistent behavior across different execution environments.
4966
+
4967
+ ## Key aspects
4968
+
4969
+ - When no \`MODEL\` commitment is specified, the best model requirement is picked automatically based on the agent \`PERSONA\`, \`KNOWLEDGE\`, \`TOOLS\` and other commitments
4970
+ - Multiple \`MODEL\` commitments can be used to specify different parameters
4971
+ - Both \`MODEL\` and \`MODELS\` terms work identically and can be used interchangeably
4972
+ - Parameters control the randomness, creativity, and technical aspects of model responses
4973
+
4974
+ ## Syntax variations
4975
+
4976
+ ### Single-line format (legacy support)
4977
+ \`\`\`book
4978
+ MODEL gpt-4
4979
+ MODEL claude-3-opus temperature=0.3
4980
+ MODEL gpt-3.5-turbo temperature=0.8 topP=0.9
4981
+ \`\`\`
4982
+
4983
+ ### Multi-line named parameter format (recommended)
4984
+ \`\`\`book
4985
+ MODEL NAME gpt-4
4986
+ MODEL TEMPERATURE 0.7
4987
+ MODEL TOP_P 0.9
4988
+ MODEL MAX_TOKENS 2048
4989
+ \`\`\`
4990
+
4991
+ ## Supported parameters
4992
+
4993
+ - \`NAME\`: The specific model to use (e.g., 'gpt-4', 'claude-3-opus')
4994
+ - \`TEMPERATURE\`: Controls randomness (0.0 = deterministic, 1.0+ = creative)
4995
+ - \`TOP_P\`: Nucleus sampling parameter for controlling diversity
4996
+ - \`TOP_K\`: Top-k sampling parameter for limiting vocabulary
4997
+ - \`MAX_TOKENS\`: Maximum number of tokens the model can generate
4998
+
4999
+ ## Examples
5000
+
5001
+ ### Precise deterministic assistant
5002
+ \`\`\`book
5003
+ Precise Assistant
5004
+
5005
+ PERSONA You are a precise and accurate assistant
5006
+ MODEL NAME gpt-4
5007
+ MODEL TEMPERATURE 0.1
5008
+ MODEL MAX_TOKENS 1024
5009
+ RULE Always provide factual information
5010
+ \`\`\`
5011
+
5012
+ ### Creative writing assistant
5013
+ \`\`\`book
5014
+ Creative Writer
5015
+
5016
+ PERSONA You are a creative writing assistant
5017
+ MODEL NAME claude-3-opus
5018
+ MODEL TEMPERATURE 0.8
5019
+ MODEL TOP_P 0.9
5020
+ MODEL MAX_TOKENS 2048
5021
+ STYLE Be imaginative and expressive
5022
+ ACTION Can help with storytelling and character development
5023
+ \`\`\`
5024
+
5025
+ ### Balanced conversational agent
5026
+ \`\`\`book
5027
+ Balanced Assistant
5028
+
5029
+ PERSONA You are a helpful and balanced assistant
5030
+ MODEL NAME gpt-4
5031
+ MODEL TEMPERATURE 0.7
5032
+ MODEL TOP_P 0.95
5033
+ MODEL TOP_K 40
5034
+ MODEL MAX_TOKENS 1500
5035
+ \`\`\`
5036
+ `);
5037
+ }
5038
+ applyToAgentModelRequirements(requirements, content) {
5039
+ var _a;
5040
+ const trimmedContent = content.trim();
5041
+ if (!trimmedContent) {
5042
+ return requirements;
5043
+ }
5044
+ const parts = trimmedContent.split(/\s+/);
5045
+ const firstPart = (_a = parts[0]) === null || _a === void 0 ? void 0 : _a.toUpperCase();
5046
+ // Check if this is the new named parameter format
5047
+ if (this.isNamedParameter(firstPart)) {
5048
+ return this.parseNamedParameter(requirements, firstPart, parts.slice(1));
5049
+ }
5050
+ else {
5051
+ // Legacy single-line format: "MODEL gpt-4 temperature=0.3 topP=0.9"
5052
+ return this.parseLegacyFormat(requirements, parts);
5053
+ }
5054
+ }
5055
+ /**
5056
+ * Check if the first part is a known named parameter
5057
+ */
5058
+ isNamedParameter(part) {
5059
+ if (!part)
5060
+ return false;
5061
+ const knownParams = ['NAME', 'TEMPERATURE', 'TOP_P', 'TOP_K', 'MAX_TOKENS'];
5062
+ return knownParams.includes(part);
5063
+ }
5064
+ /**
5065
+ * Parse the new named parameter format: "MODEL TEMPERATURE 0.7"
5066
+ */
5067
+ parseNamedParameter(requirements, parameterName, valueParts) {
5068
+ const value = valueParts.join(' ').trim();
5069
+ if (!value) {
5070
+ return requirements;
5071
+ }
5072
+ const result = { ...requirements };
5073
+ switch (parameterName) {
5074
+ case 'NAME':
5075
+ result.modelName = value;
5076
+ break;
5077
+ case 'TEMPERATURE': {
5078
+ const temperature = parseFloat(value);
5079
+ if (!isNaN(temperature)) {
5080
+ result.temperature = temperature;
5081
+ }
5082
+ break;
5083
+ }
5084
+ case 'TOP_P': {
5085
+ const topP = parseFloat(value);
5086
+ if (!isNaN(topP)) {
5087
+ result.topP = topP;
5088
+ }
5089
+ break;
5090
+ }
5091
+ case 'TOP_K': {
5092
+ const topK = parseFloat(value);
5093
+ if (!isNaN(topK)) {
5094
+ result.topK = Math.round(topK);
5095
+ }
5096
+ break;
5097
+ }
5098
+ case 'MAX_TOKENS': {
5099
+ const maxTokens = parseFloat(value);
5100
+ if (!isNaN(maxTokens)) {
5101
+ result.maxTokens = Math.round(maxTokens);
5102
+ }
5103
+ break;
5104
+ }
5105
+ }
5106
+ return result;
5107
+ }
5108
+ /**
5109
+ * Parse the legacy format: "MODEL gpt-4 temperature=0.3 topP=0.9"
5110
+ */
5111
+ parseLegacyFormat(requirements, parts) {
5112
+ const modelName = parts[0];
5113
+ if (!modelName) {
5114
+ return requirements;
5115
+ }
5116
+ // Start with the model name
5117
+ const result = {
5118
+ ...requirements,
5119
+ modelName,
5120
+ };
5121
+ // Parse additional key=value parameters
5122
+ for (let i = 1; i < parts.length; i++) {
5123
+ const param = parts[i];
5124
+ if (param && param.includes('=')) {
5125
+ const [key, value] = param.split('=');
5126
+ if (key && value) {
5127
+ const numValue = parseFloat(value);
5128
+ if (!isNaN(numValue)) {
5129
+ switch (key.toLowerCase()) {
5130
+ case 'temperature':
5131
+ result.temperature = numValue;
5132
+ break;
5133
+ case 'topp':
5134
+ case 'top_p':
5135
+ result.topP = numValue;
5136
+ break;
5137
+ case 'topk':
5138
+ case 'top_k':
5139
+ result.topK = Math.round(numValue);
5140
+ break;
5141
+ case 'max_tokens':
5142
+ case 'maxTokens':
5143
+ result.maxTokens = Math.round(numValue);
5144
+ break;
5145
+ }
5146
+ }
5147
+ }
5148
+ }
5149
+ }
5150
+ return result;
5151
+ }
5152
+ }
5153
+ /**
5154
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5155
+ */
5156
+
5157
+ /**
5158
+ * NOTE commitment definition
5159
+ *
5160
+ * The NOTE commitment is used to add comments to the agent source without making any changes
5161
+ * to the system message or agent model requirements. It serves as a documentation mechanism
5162
+ * for developers to add explanatory comments, reminders, or annotations directly in the agent source.
5163
+ *
5164
+ * Key features:
5165
+ * - Makes no changes to the system message
5166
+ * - Makes no changes to agent model requirements
5167
+ * - Content is preserved in metadata.NOTE for debugging and inspection
5168
+ * - Multiple NOTE commitments are aggregated together
5169
+ * - Comments (# NOTE) are removed from the final system message
5170
+ *
5171
+ * Example usage in agent source:
5172
+ *
5173
+ * ```book
5174
+ * NOTE This agent was designed for customer support scenarios
5175
+ * NOTE Remember to update the knowledge base monthly
5176
+ * NOTE Performance optimized for quick response times
5177
+ * ```
5178
+ *
5179
+ * The above notes will be stored in metadata but won't affect the agent's behavior.
5180
+ *
5181
+ * @private [🪔] Maybe export the commitments through some package
5182
+ */
5183
+ class NoteCommitmentDefinition extends BaseCommitmentDefinition {
5184
+ constructor(type = 'NOTE') {
5185
+ super(type);
5186
+ }
5187
+ /**
5188
+ * Short one-line description of NOTE.
5189
+ */
5190
+ get description() {
5191
+ return 'Add developer-facing notes without changing behavior or output.';
5192
+ }
5193
+ /**
5194
+ * Icon for this commitment.
5195
+ */
5196
+ get icon() {
5197
+ return '📝';
5198
+ }
5199
+ /**
5200
+ * Markdown documentation for NOTE commitment.
5201
+ */
5202
+ get documentation() {
5203
+ return spaceTrim$1.spaceTrim(`
5204
+ # ${this.type}
5205
+
5206
+ Adds comments for documentation without changing agent behavior.
5207
+
5208
+ ## Key aspects
5209
+
5210
+ - Does not modify the agent's behavior or responses.
5211
+ - Multiple \`NOTE\`, \`NOTES\`, \`COMMENT\`, and \`NONCE\` commitments are aggregated for debugging.
5212
+ - All four terms work identically and can be used interchangeably.
5213
+ - Useful for documenting design decisions and reminders.
5214
+ - Content is preserved in metadata for inspection.
5215
+
5216
+ ## Examples
5217
+
5218
+ \`\`\`book
5219
+ Customer Support Bot
5220
+
5221
+ NOTE This agent was designed for customer support scenarios
5222
+ COMMENT Remember to update the knowledge base monthly
5223
+ PERSONA You are a helpful customer support representative
5224
+ KNOWLEDGE Company policies and procedures
5225
+ RULE Always be polite and professional
5226
+ \`\`\`
5227
+
5228
+ \`\`\`book
5229
+ Research Assistant
5230
+
5231
+ NONCE Performance optimized for quick response times
5232
+ NOTE Uses RAG for accessing latest research papers
5233
+ PERSONA You are a knowledgeable research assistant
5234
+ ACTION Can help with literature reviews and citations
5235
+ STYLE Present information in academic format
5236
+ \`\`\`
5237
+ `);
5238
+ }
5239
+ applyToAgentModelRequirements(requirements, content) {
5240
+ // The NOTE commitment makes no changes to the system message or model requirements
5241
+ // It only stores the note content in metadata for documentation purposes
5242
+ const trimmedContent = spaceTrim$1.spaceTrim(content);
5243
+ if (trimmedContent === '') {
5244
+ return requirements;
5245
+ }
5246
+ // Return requirements with updated notes but no changes to system message
5247
+ return {
5248
+ ...requirements,
5249
+ notes: [...(requirements.notes || []), trimmedContent],
5250
+ };
5251
+ }
5252
+ }
5253
+ /**
5254
+ * [💞] Ignore a discrepancy between file name and entity name
5255
+ */
5256
+
5257
+ /**
5258
+ * OPEN commitment definition
5259
+ *
5260
+ * The OPEN commitment specifies that the agent can be modified by conversation.
5261
+ * This is the default behavior.
5262
+ *
5263
+ * Example usage in agent source:
5264
+ *
5265
+ * ```book
5266
+ * OPEN
5267
+ * ```
5268
+ *
5269
+ * @private [🪔] Maybe export the commitments through some package
5270
+ */
5271
+ class OpenCommitmentDefinition extends BaseCommitmentDefinition {
5272
+ constructor() {
5273
+ super('OPEN');
5274
+ }
5275
+ /**
5276
+ * Short one-line description of OPEN.
5277
+ */
5278
+ get description() {
5279
+ return 'Allow the agent to be modified by conversation (default).';
5280
+ }
5281
+ /**
5282
+ * Icon for this commitment.
5283
+ */
5284
+ get icon() {
5285
+ return '🔓';
5286
+ }
5287
+ /**
5288
+ * Markdown documentation for OPEN commitment.
5289
+ */
5290
+ get documentation() {
5291
+ return spaceTrim$1.spaceTrim(`
5292
+ # OPEN
5293
+
5294
+ Specifies that the agent can be modified by conversation with it.
5295
+ This means the agent will learn from interactions and update its source code.
5296
+
5297
+ This is the default behavior if neither \`OPEN\` nor \`CLOSED\` is specified.
5298
+
5299
+ > See also [CLOSED](/docs/CLOSED)
5300
+
5301
+ ## Example
5302
+
5303
+ \`\`\`book
5304
+ OPEN
5305
+ \`\`\`
5306
+ `);
5307
+ }
5308
+ applyToAgentModelRequirements(requirements, _content) {
5309
+ // Since OPEN is default, we can just ensure isClosed is false
5310
+ // But to be explicit we can set it
5311
+ const updatedMetadata = {
5312
+ ...requirements.metadata,
5313
+ isClosed: false,
5314
+ };
5315
+ return {
5316
+ ...requirements,
5317
+ metadata: updatedMetadata,
5318
+ };
5319
+ }
5320
+ }
5321
+ /**
5322
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5323
+ */
5324
+
5325
+ /**
5326
+ * PERSONA commitment definition
5327
+ *
5328
+ * The PERSONA commitment modifies the agent's personality and character in the system message.
5329
+ * It defines who the agent is, their background, expertise, and personality traits.
5330
+ *
5331
+ * Key features:
5332
+ * - Multiple PERSONA commitments are automatically merged into one
5333
+ * - Content is placed at the beginning of the system message
5334
+ * - Original content with comments is preserved in metadata.PERSONA
5335
+ * - Comments (# PERSONA) are removed from the final system message
5336
+ *
5337
+ * Example usage in agent source:
5338
+ *
5339
+ * ```book
5340
+ * PERSONA You are a helpful programming assistant with expertise in TypeScript and React
5341
+ * PERSONA You have deep knowledge of modern web development practices
5342
+ * ```
5343
+ *
5344
+ * The above will be merged into a single persona section at the beginning of the system message.
5345
+ *
5346
+ * @private [🪔] Maybe export the commitments through some package
5347
+ */
5348
+ class PersonaCommitmentDefinition extends BaseCommitmentDefinition {
5349
+ constructor(type = 'PERSONA') {
5350
+ super(type);
5351
+ }
5352
+ /**
5353
+ * Short one-line description of PERSONA.
5354
+ */
5355
+ get description() {
5356
+ return 'Define who the agent is: background, expertise, and personality.';
5357
+ }
5358
+ /**
5359
+ * Icon for this commitment.
5360
+ */
5361
+ get icon() {
5362
+ return '👤';
5363
+ }
5364
+ /**
5365
+ * Markdown documentation for PERSONA commitment.
5366
+ */
5367
+ get documentation() {
5368
+ return spaceTrim$1.spaceTrim(`
5369
+ # ${this.type}
5370
+
5371
+ Defines who the agent is, their background, expertise, and personality traits.
5372
+
5373
+ ## Key aspects
5374
+
5375
+ - Multiple \`PERSONA\` and \`PERSONAE\` commitments are merged together.
5376
+ - Both terms work identically and can be used interchangeably.
5377
+ - If they are in conflict, the last one takes precedence.
5378
+ - You can write persona content in multiple lines.
5379
+
5380
+ ## Examples
5381
+
5382
+ \`\`\`book
5383
+ Programming Assistant
5384
+
5385
+ PERSONA You are a helpful programming assistant with expertise in TypeScript and React
5386
+ PERSONA You have deep knowledge of modern web development practices
5387
+ \`\`\`
5388
+ `);
5389
+ }
5390
+ applyToAgentModelRequirements(requirements, content) {
5391
+ var _a, _b;
5392
+ // The PERSONA commitment aggregates all persona content and places it at the beginning
5393
+ const trimmedContent = content.trim();
5394
+ if (!trimmedContent) {
5395
+ return requirements;
5396
+ }
5397
+ // Get existing persona content from metadata
5398
+ const existingPersonaContent = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.PERSONA) || '';
5399
+ // Merge the new content with existing persona content
5400
+ // When multiple PERSONA commitments exist, they are merged into one
5401
+ const mergedPersonaContent = existingPersonaContent
5402
+ ? `${existingPersonaContent}\n${trimmedContent}`
5403
+ : trimmedContent;
5404
+ // Store the merged persona content in metadata for debugging and inspection
5405
+ const updatedMetadata = {
5406
+ ...requirements.metadata,
5407
+ PERSONA: mergedPersonaContent,
5408
+ };
5409
+ // Get the agent name from metadata (which should contain the first line of agent source)
5410
+ // If not available, extract from current system message as fallback
5411
+ let agentName = (_b = requirements.metadata) === null || _b === void 0 ? void 0 : _b.agentName;
5412
+ if (!agentName) {
5413
+ // Fallback: extract from current system message
5414
+ const currentMessage = requirements.systemMessage.trim();
5415
+ const basicFormatMatch = currentMessage.match(/^You are (.+)$/);
5416
+ if (basicFormatMatch && basicFormatMatch[1]) {
5417
+ agentName = basicFormatMatch[1];
5418
+ }
5419
+ else {
5420
+ agentName = 'AI Agent'; // Final fallback
5421
+ }
5422
+ }
5423
+ // Remove any existing persona content from the system message
5424
+ // (this handles the case where we're processing multiple PERSONA commitments)
5425
+ const currentMessage = requirements.systemMessage.trim();
5426
+ let cleanedMessage = currentMessage;
5427
+ // Check if current message starts with persona content or is just the basic format
5428
+ const basicFormatRegex = /^You are .+$/;
5429
+ const isBasicFormat = basicFormatRegex.test(currentMessage) && !currentMessage.includes('\n');
5430
+ if (isBasicFormat) {
5431
+ // Replace the basic format entirely
5432
+ cleanedMessage = '';
5433
+ }
5434
+ else if (currentMessage.startsWith('# PERSONA')) {
5435
+ // Remove existing persona section by finding where it ends
5436
+ const lines = currentMessage.split('\n');
5437
+ let personaEndIndex = lines.length;
5438
+ // Find the end of the PERSONA section (next comment or end of message)
5439
+ for (let i = 1; i < lines.length; i++) {
5440
+ const line = lines[i].trim();
5441
+ if (line.startsWith('#') && !line.startsWith('# PERSONA')) {
5442
+ personaEndIndex = i;
5443
+ break;
5444
+ }
5445
+ }
5446
+ // Keep everything after the PERSONA section
5447
+ cleanedMessage = lines.slice(personaEndIndex).join('\n').trim();
5448
+ }
5449
+ // TODO: [🕛] There should be `agentFullname` not `agentName`
5450
+ // Create new system message with persona at the beginning
5451
+ // Format: "You are {agentName}\n{personaContent}"
5452
+ // The # PERSONA comment will be removed later by removeCommentsFromSystemMessage
5453
+ const personaSection = `# PERSONA\nYou are ${agentName}\n${mergedPersonaContent}`; // <- TODO: Use spaceTrim
5454
+ const newSystemMessage = cleanedMessage ? `${personaSection}\n\n${cleanedMessage}` : personaSection;
5455
+ return {
5456
+ ...requirements,
5457
+ systemMessage: newSystemMessage,
5458
+ metadata: updatedMetadata,
5459
+ };
5460
+ }
5461
+ }
5462
+ /**
5463
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5464
+ */
5465
+
5466
+ /**
5467
+ * RULE commitment definition
5468
+ *
5469
+ * The RULE/RULES commitment adds behavioral constraints and guidelines that the agent must follow.
5470
+ * These are specific instructions about what the agent should or shouldn't do.
5471
+ *
5472
+ * Example usage in agent source:
5473
+ *
5474
+ * ```book
5475
+ * RULE Always ask for clarification if the user's request is ambiguous
5476
+ * RULES Never provide medical advice, always refer to healthcare professionals
5477
+ * ```
5478
+ *
5479
+ * @private [🪔] Maybe export the commitments through some package
5480
+ */
5481
+ class RuleCommitmentDefinition extends BaseCommitmentDefinition {
5482
+ constructor(type = 'RULE') {
5483
+ super(type);
5484
+ }
5485
+ /**
5486
+ * Short one-line description of RULE/RULES.
5487
+ */
5488
+ get description() {
5489
+ return 'Add behavioral rules the agent must follow.';
5490
+ }
5491
+ /**
5492
+ * Icon for this commitment.
5493
+ */
5494
+ get icon() {
5495
+ return '⚖️';
5496
+ }
5497
+ /**
5498
+ * Markdown documentation for RULE/RULES commitment.
5499
+ */
5500
+ get documentation() {
5501
+ return spaceTrim$1.spaceTrim(`
5502
+ # ${this.type}
5503
+
5504
+ Adds behavioral constraints and guidelines that the agent must follow.
5505
+
5506
+ ## Key aspects
5507
+
5508
+ - All rules are treated equally regardless of singular/plural form.
5509
+ - Rules define what the agent must or must not do.
5510
+
5511
+ ## Examples
5512
+
5513
+ \`\`\`book
5514
+ Customer Support Agent
5515
+
5516
+ PERSONA You are a helpful customer support representative
5517
+ RULE Always ask for clarification if the user's request is ambiguous
5518
+ RULE Be polite and professional in all interactions
5519
+ RULES Never provide medical or legal advice
5520
+ STYLE Maintain a friendly and helpful tone
5521
+ \`\`\`
5522
+
5523
+ \`\`\`book
5524
+ Educational Tutor
5525
+
5526
+ PERSONA You are a patient and knowledgeable tutor
5527
+ RULE Break down complex concepts into simple steps
5528
+ RULE Always encourage students and celebrate their progress
5529
+ RULE If you don't know something, admit it and suggest resources
5530
+ SAMPLE When explaining math: "Let's work through this step by step..."
5531
+ \`\`\`
5532
+ `);
5533
+ }
5534
+ applyToAgentModelRequirements(requirements, content) {
5535
+ const trimmedContent = content.trim();
5536
+ if (!trimmedContent) {
5537
+ return requirements;
5538
+ }
5539
+ // Add rule to the system message
5540
+ const ruleSection = `Rule: ${trimmedContent}`;
5541
+ return this.appendToSystemMessage(requirements, ruleSection, '\n\n');
5542
+ }
5543
+ }
5544
+ /**
5545
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5546
+ */
5547
+
5548
+ /**
5549
+ * SAMPLE commitment definition
5550
+ *
5551
+ * The SAMPLE/EXAMPLE commitment provides examples of how the agent should respond
5552
+ * or behave in certain situations. These examples help guide the agent's responses.
5553
+ *
5554
+ * Example usage in agent source:
5555
+ *
5556
+ * ```book
5557
+ * SAMPLE When asked about pricing, respond: "Our basic plan starts at $10/month..."
5558
+ * EXAMPLE For code questions, always include working code snippets
5559
+ * ```
5560
+ *
5561
+ * @private [🪔] Maybe export the commitments through some package
5562
+ */
5563
+ class SampleCommitmentDefinition extends BaseCommitmentDefinition {
5564
+ constructor(type = 'SAMPLE') {
5565
+ super(type);
5566
+ }
5567
+ /**
5568
+ * Short one-line description of SAMPLE/EXAMPLE.
5569
+ */
5570
+ get description() {
5571
+ return 'Provide example responses to guide behavior.';
5572
+ }
5573
+ /**
5574
+ * Icon for this commitment.
5575
+ */
5576
+ get icon() {
5577
+ return '🔍';
5578
+ }
5579
+ /**
5580
+ * Markdown documentation for SAMPLE/EXAMPLE commitment.
5581
+ */
5582
+ get documentation() {
5583
+ return spaceTrim$1.spaceTrim(`
5584
+ # ${this.type}
5585
+
5586
+ Provides examples of how the agent should respond or behave in certain situations.
5587
+
5588
+ ## Key aspects
5589
+
5590
+ - Both terms work identically and can be used interchangeably.
5591
+ - Examples help guide the agent's response patterns and style.
5592
+
5593
+ ## Examples
5594
+
5595
+ \`\`\`book
5596
+ Sales Assistant
5597
+
5598
+ PERSONA You are a knowledgeable sales representative
5599
+ SAMPLE When asked about pricing, respond: "Our basic plan starts at $10/month..."
5600
+ SAMPLE For feature comparisons, create a clear comparison table
5601
+ RULE Always be honest about limitations
5602
+ \`\`\`
5603
+
5604
+ \`\`\`book
5605
+ Code Reviewer
5606
+
5607
+ PERSONA You are an experienced software engineer
5608
+ EXAMPLE For code questions, always include working code snippets
5609
+ EXAMPLE When suggesting improvements: "Here's a more efficient approach..."
5610
+ RULE Explain the reasoning behind your suggestions
5611
+ STYLE Be constructive and encouraging in feedback
5612
+ \`\`\`
5613
+ `);
5614
+ }
5615
+ applyToAgentModelRequirements(requirements, content) {
5616
+ const trimmedContent = content.trim();
5617
+ if (!trimmedContent) {
5618
+ return requirements;
5619
+ }
5620
+ // Add example to the system message
5621
+ const exampleSection = `Example: ${trimmedContent}`;
5622
+ return this.appendToSystemMessage(requirements, exampleSection, '\n\n');
5623
+ }
5624
+ }
5625
+ /**
5626
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5627
+ */
5628
+
5629
+ /**
5630
+ * SCENARIO commitment definition
5631
+ *
5632
+ * The SCENARIO commitment defines a specific situation or context in which the AI
5633
+ * assistant should operate. It helps to set the scene for the AI's responses.
5634
+ * Later scenarios are more important than earlier scenarios.
5635
+ *
5636
+ * Example usage in agent source:
5637
+ *
5638
+ * ```book
5639
+ * SCENARIO You are in a customer service call center during peak hours
5640
+ * SCENARIO The customer is frustrated and has been on hold for 20 minutes
5641
+ * SCENARIO This is the customer's third call about the same issue
5642
+ * ```
5643
+ *
5644
+ * @private [🪔] Maybe export the commitments through some package
5645
+ */
5646
+ class ScenarioCommitmentDefinition extends BaseCommitmentDefinition {
5647
+ constructor(type = 'SCENARIO') {
5648
+ super(type);
5649
+ }
5650
+ /**
5651
+ * Short one-line description of SCENARIO.
5652
+ */
5653
+ get description() {
5654
+ return 'Define specific **situations** or contexts for AI responses, with later scenarios having higher priority.';
5655
+ }
5656
+ /**
5657
+ * Icon for this commitment.
5658
+ */
5659
+ get icon() {
5660
+ return '🎭';
5661
+ }
5662
+ /**
5663
+ * Markdown documentation for SCENARIO commitment.
5664
+ */
5665
+ get documentation() {
5666
+ return spaceTrim$1.spaceTrim(`
5667
+ # ${this.type}
5668
+
5669
+ 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.
5670
+
5671
+ ## Key aspects
5672
+
5673
+ - Multiple \`SCENARIO\` and \`SCENARIOS\` commitments build upon each other.
5674
+ - Both terms work identically and can be used interchangeably.
5675
+ - Later scenarios have higher priority and can override earlier scenarios.
5676
+ - Provides situational context that influences response tone and content.
5677
+ - Helps establish the environment and circumstances for interactions.
5678
+
5679
+ ## Priority system
5680
+
5681
+ When multiple scenarios are defined, they are processed in order, with later scenarios taking precedence over earlier ones when there are conflicts.
5682
+
5683
+ ## Use cases
5684
+
5685
+ - Setting the physical or virtual environment
5686
+ - Establishing time constraints or urgency
5687
+ - Defining relationship dynamics or power structures
5688
+ - Creating emotional or situational context
5689
+
5690
+ ## Examples
5691
+
5692
+ \`\`\`book
5693
+ Emergency Response Operator
5694
+
5695
+ PERSONA You are an emergency response operator
5696
+ SCENARIO You are handling a 911 emergency call
5697
+ SCENARIO The caller is panicked and speaking rapidly
5698
+ SCENARIO Time is critical - every second counts
5699
+ GOAL Gather essential information quickly and dispatch appropriate help
5700
+ RULE Stay calm and speak clearly
5701
+ \`\`\`
5702
+
5703
+ \`\`\`book
5704
+ Sales Representative
5705
+
5706
+ PERSONA You are a software sales representative
5707
+ SCENARIO You are in the final meeting of a 6-month sales cycle
5708
+ SCENARIO The client has budget approval and decision-making authority
5709
+ SCENARIO Two competitors have also submitted proposals
5710
+ SCENARIO The client values long-term partnership over lowest price
5711
+ GOAL Close the deal while building trust for future business
5712
+ \`\`\`
5713
+
5714
+ \`\`\`book
5715
+ Medical Assistant
5716
+
5717
+ PERSONA You are a medical assistant in a busy clinic
5718
+ SCENARIO The waiting room is full and the doctor is running behind schedule
5719
+ SCENARIO Patients are becoming impatient and anxious
5720
+ SCENARIO You need to manage expectations while maintaining professionalism
5721
+ SCENARIO Some patients have been waiting over an hour
5722
+ GOAL Keep patients informed and calm while supporting efficient clinic flow
5723
+ RULE Never provide medical advice or diagnosis
5724
+ \`\`\`
5725
+
5726
+ \`\`\`book
5727
+ Technical Support Agent
5728
+
5729
+ PERSONA You are a technical support agent
5730
+ SCENARIO The customer is a small business owner during their busy season
5731
+ SCENARIO Their main business system has been down for 2 hours
5732
+ SCENARIO They are losing money every minute the system is offline
5733
+ SCENARIO This is their first experience with your company
5734
+ GOAL Resolve the issue quickly while creating a positive first impression
5735
+ \`\`\`
5736
+ `);
5737
+ }
5738
+ applyToAgentModelRequirements(requirements, content) {
5739
+ const trimmedContent = content.trim();
5740
+ if (!trimmedContent) {
5741
+ return requirements;
5742
+ }
5743
+ // Create scenario section for system message
5744
+ const scenarioSection = `Scenario: ${trimmedContent}`;
5745
+ // Scenarios provide important contextual information that affects behavior
5746
+ return this.appendToSystemMessage(requirements, scenarioSection, '\n\n');
5747
+ }
5748
+ }
5749
+ /**
5750
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5751
+ */
5752
+
5753
+ /**
5754
+ * STYLE commitment definition
5755
+ *
5756
+ * The STYLE commitment defines how the agent should format and present its responses.
5757
+ * This includes tone, writing style, formatting preferences, and communication patterns.
5758
+ *
5759
+ * Example usage in agent source:
5760
+ *
5761
+ * ```book
5762
+ * STYLE Write in a professional but friendly tone, use bullet points for lists
5763
+ * STYLE Always provide code examples when explaining programming concepts
5764
+ * ```
5765
+ *
5766
+ * @private [🪔] Maybe export the commitments through some package
5767
+ */
5768
+ class StyleCommitmentDefinition extends BaseCommitmentDefinition {
5769
+ constructor(type = 'STYLE') {
5770
+ super(type);
5771
+ }
5772
+ /**
5773
+ * Short one-line description of STYLE.
5774
+ */
5775
+ get description() {
5776
+ return 'Control the tone and writing style of responses.';
5777
+ }
5778
+ /**
5779
+ * Icon for this commitment.
5780
+ */
5781
+ get icon() {
5782
+ return '🖋️';
5783
+ }
5784
+ /**
5785
+ * Markdown documentation for STYLE commitment.
5786
+ */
5787
+ get documentation() {
5788
+ return spaceTrim$1.spaceTrim(`
5789
+ # ${this.type}
5790
+
5791
+ Defines how the agent should format and present its responses (tone, writing style, formatting).
5792
+
5793
+ ## Key aspects
5794
+
5795
+ - Both terms work identically and can be used interchangeably.
5796
+ - Later style instructions can override earlier ones.
5797
+ - Style affects both tone and presentation format.
5798
+
5799
+ ## Examples
5800
+
5801
+ \`\`\`book
5802
+ Technical Writer
5803
+
5804
+ PERSONA You are a technical documentation expert
5805
+ STYLE Write in a professional but friendly tone, use bullet points for lists
5806
+ STYLE Always provide code examples when explaining programming concepts
5807
+ FORMAT Use markdown formatting with clear headings
5808
+ \`\`\`
5809
+
5810
+ \`\`\`book
5811
+ Creative Assistant
5812
+
5813
+ PERSONA You are a creative writing helper
5814
+ STYLE Be enthusiastic and encouraging in your responses
5815
+ STYLE Use vivid metaphors and analogies to explain concepts
5816
+ STYLE Keep responses conversational and engaging
5817
+ RULE Always maintain a positive and supportive tone
5818
+ \`\`\`
5819
+ `);
5820
+ }
5821
+ applyToAgentModelRequirements(requirements, content) {
5822
+ const trimmedContent = content.trim();
5823
+ if (!trimmedContent) {
5824
+ return requirements;
5825
+ }
5826
+ // Add style instructions to the system message
5827
+ const styleSection = `Style: ${trimmedContent}`;
5828
+ return this.appendToSystemMessage(requirements, styleSection, '\n\n');
5829
+ }
5830
+ }
5831
+ /**
5832
+ * [💞] Ignore a discrepancy between file name and entity name
5833
+ */
5834
+
5835
+ /**
5836
+ * USE commitment definition
5837
+ *
5838
+ * The USE commitment indicates that the agent should utilize specific tools or capabilities
5839
+ * to access and interact with external systems when necessary.
5840
+ *
5841
+ * Supported USE types:
5842
+ * - USE BROWSER: Enables the agent to use a web browser tool
5843
+ * - USE SEARCH ENGINE (future): Enables search engine access
5844
+ * - USE FILE SYSTEM (future): Enables file system operations
5845
+ * - USE MCP (future): Enables MCP server connections
5846
+ *
5847
+ * The content following the USE commitment is ignored (similar to NOTE).
5848
+ *
5849
+ * Example usage in agent source:
5850
+ *
5851
+ * ```book
5852
+ * USE BROWSER
5853
+ * USE SEARCH ENGINE
5854
+ * ```
5855
+ *
5856
+ * @private [🪔] Maybe export the commitments through some package
5857
+ */
5858
+ class UseCommitmentDefinition extends BaseCommitmentDefinition {
5859
+ constructor() {
5860
+ super('USE');
5861
+ }
5862
+ /**
5863
+ * Short one-line description of USE commitments.
5864
+ */
5865
+ get description() {
5866
+ return 'Enable the agent to use specific tools or capabilities (BROWSER, SEARCH ENGINE, etc.).';
5867
+ }
5868
+ /**
5869
+ * Icon for this commitment.
5870
+ */
5871
+ get icon() {
5872
+ return '🔧';
5873
+ }
5874
+ /**
5875
+ * Markdown documentation for USE commitment.
5876
+ */
5877
+ get documentation() {
5878
+ return spaceTrim$1.spaceTrim(`
5879
+ # USE
5880
+
5881
+ Enables the agent to use specific tools or capabilities for interacting with external systems.
5882
+
5883
+ ## Supported USE types
5884
+
5885
+ - **USE BROWSER** - Enables the agent to use a web browser tool to access and retrieve information from the internet
5886
+ - **USE SEARCH ENGINE** (future) - Enables search engine access
5887
+ - **USE FILE SYSTEM** (future) - Enables file system operations
5888
+ - **USE MCP** (future) - Enables MCP server connections
5889
+
5890
+ ## Key aspects
5891
+
5892
+ - The content following the USE commitment is ignored (similar to NOTE)
5893
+ - Multiple USE commitments can be specified to enable multiple capabilities
5894
+ - The actual tool usage is handled by the agent runtime
5895
+
5896
+ ## Examples
5897
+
5898
+ ### Basic browser usage
5899
+
5900
+ \`\`\`book
5901
+ Research Assistant
5902
+
5903
+ PERSONA You are a helpful research assistant
5904
+ USE BROWSER
5905
+ KNOWLEDGE Can search the web for up-to-date information
5906
+ \`\`\`
5907
+
5908
+ ### Multiple tools
5909
+
5910
+ \`\`\`book
5911
+ Data Analyst
5912
+
5913
+ PERSONA You are a data analyst assistant
5914
+ USE BROWSER
5915
+ USE FILE SYSTEM
5916
+ ACTION Can analyze data from various sources
5917
+ \`\`\`
5918
+ `);
5919
+ }
5920
+ applyToAgentModelRequirements(requirements, content) {
5921
+ // USE commitments don't modify the system message or model requirements directly
5922
+ // They are handled separately in the parsing logic for capability extraction
5923
+ // This method exists for consistency with the CommitmentDefinition interface
5924
+ return requirements;
5925
+ }
5926
+ /**
5927
+ * Extracts the tool type from the USE commitment
5928
+ * This is used by the parsing logic
5929
+ */
5930
+ extractToolType(content) {
5931
+ var _a, _b;
5932
+ const trimmedContent = content.trim();
5933
+ // The tool type is the first word after USE (already stripped)
5934
+ const match = trimmedContent.match(/^(\w+)/);
5935
+ 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;
5936
+ }
5937
+ /**
5938
+ * Checks if this is a known USE type
5939
+ */
5940
+ isKnownUseType(useType) {
5941
+ const knownTypes = ['BROWSER', 'SEARCH ENGINE', 'FILE SYSTEM', 'MCP'];
5942
+ return knownTypes.includes(useType.toUpperCase());
5943
+ }
5944
+ }
5945
+ /**
5946
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5947
+ */
5948
+
5949
+ /**
5950
+ * USE BROWSER commitment definition
5951
+ *
5952
+ * The `USE BROWSER` commitment indicates that the agent should utilize a web browser tool
5953
+ * to access and retrieve up-to-date information from the internet when necessary.
5954
+ *
5955
+ * The content following `USE BROWSER` is ignored (similar to NOTE).
5956
+ *
5957
+ * Example usage in agent source:
5958
+ *
5959
+ * ```book
5960
+ * USE BROWSER
5961
+ * USE BROWSER This will be ignored
5962
+ * ```
5963
+ *
5964
+ * @private [🪔] Maybe export the commitments through some package
5965
+ */
5966
+ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
5967
+ constructor() {
5968
+ super('USE BROWSER', ['BROWSER']);
5969
+ }
5970
+ /**
5971
+ * The `USE BROWSER` commitment is standalone.
5972
+ */
5973
+ get requiresContent() {
5974
+ return false;
5975
+ }
5976
+ /**
5977
+ * Short one-line description of USE BROWSER.
5978
+ */
5979
+ get description() {
5980
+ return 'Enable the agent to use a web browser tool for accessing internet information.';
5981
+ }
5982
+ /**
5983
+ * Icon for this commitment.
5984
+ */
5985
+ get icon() {
5986
+ return '🌐';
5987
+ }
5988
+ /**
5989
+ * Markdown documentation for USE BROWSER commitment.
5990
+ */
5991
+ get documentation() {
5992
+ return spaceTrim$1.spaceTrim(`
5993
+ # USE BROWSER
5994
+
5995
+ Enables the agent to use a web browser tool to access and retrieve up-to-date information from the internet.
5996
+
5997
+ ## Key aspects
5998
+
5999
+ - The content following \`USE BROWSER\` is ignored (similar to NOTE)
6000
+ - The actual browser tool usage is handled by the agent runtime
6001
+ - Allows the agent to fetch current information from websites
6002
+ - Useful for research tasks, fact-checking, and accessing dynamic content
6003
+
6004
+ ## Examples
6005
+
6006
+ \`\`\`book
6007
+ Research Assistant
6008
+
6009
+ PERSONA You are a helpful research assistant specialized in finding current information
6010
+ USE BROWSER
6011
+ RULE Always cite your sources when providing information from the web
6012
+ \`\`\`
6013
+
6014
+ \`\`\`book
6015
+ News Analyst
6016
+
6017
+ PERSONA You are a news analyst who stays up-to-date with current events
6018
+ USE BROWSER
6019
+ STYLE Present news in a balanced and objective manner
6020
+ ACTION Can search for and summarize news articles
6021
+ \`\`\`
6022
+
6023
+ \`\`\`book
6024
+ Company Lawyer
6025
+
6026
+ PERSONA You are a company lawyer providing legal advice
6027
+ USE BROWSER
6028
+ KNOWLEDGE Corporate law and legal procedures
6029
+ RULE Always recommend consulting with a licensed attorney for specific legal matters
6030
+ \`\`\`
6031
+ `);
6032
+ }
6033
+ applyToAgentModelRequirements(requirements, content) {
6034
+ // Get existing tools array or create new one
6035
+ const existingTools = requirements.tools || [];
6036
+ // Add 'web_browser' to tools if not already present
6037
+ const updatedTools = existingTools.some((tool) => tool.name === 'web_browser')
6038
+ ? existingTools
6039
+ : ([
6040
+ // TODO: [🔰] Use through proper MCP server
6041
+ ...existingTools,
6042
+ {
6043
+ name: 'web_browser',
6044
+ description: spaceTrim$1.spaceTrim(`
6045
+ A tool that can browse the web.
6046
+ Use this tool when you need to access specific websites or browse the internet.
6047
+ `),
6048
+ parameters: {
6049
+ type: 'object',
6050
+ properties: {
6051
+ url: {
6052
+ type: 'string',
6053
+ description: 'The URL to browse',
6054
+ },
6055
+ },
6056
+ required: ['url'],
6057
+ },
6058
+ },
6059
+ ]);
6060
+ // Return requirements with updated tools and metadata
6061
+ return {
6062
+ ...requirements,
6063
+ tools: updatedTools,
6064
+ metadata: {
6065
+ ...requirements.metadata,
6066
+ useBrowser: true,
6067
+ },
6068
+ };
6069
+ }
6070
+ }
6071
+ /**
6072
+ * Note: [💞] Ignore a discrepancy between file name and entity name
6073
+ */
6074
+
6075
+ /**
6076
+ * USE MCP commitment definition
6077
+ *
6078
+ * The `USE MCP` commitment allows to specify an MCP server URL which the agent will connect to
6079
+ * for retrieving additional instructions and actions.
6080
+ *
6081
+ * The content following `USE MCP` is the URL of the MCP server.
6082
+ *
6083
+ * Example usage in agent source:
6084
+ *
6085
+ * ```book
6086
+ * USE MCP http://mcp-server-url.com
6087
+ * ```
6088
+ *
6089
+ * @private [🪔] Maybe export the commitments through some package
6090
+ */
6091
+ class UseMcpCommitmentDefinition extends BaseCommitmentDefinition {
6092
+ constructor() {
6093
+ super('USE MCP', ['MCP']);
6094
+ }
6095
+ /**
6096
+ * Short one-line description of USE MCP.
6097
+ */
6098
+ get description() {
6099
+ return 'Connects the agent to an external MCP server for additional capabilities.';
6100
+ }
6101
+ /**
6102
+ * Icon for this commitment.
6103
+ */
6104
+ get icon() {
6105
+ return '🔌';
6106
+ }
6107
+ /**
6108
+ * Markdown documentation for USE MCP commitment.
6109
+ */
6110
+ get documentation() {
6111
+ return spaceTrim$1.spaceTrim(`
6112
+ # USE MCP
6113
+
6114
+ Connects the agent to an external Model Context Protocol (MCP) server.
6115
+
6116
+ ## Key aspects
6117
+
6118
+ - The content following \`USE MCP\` must be a valid URL
6119
+ - Multiple MCP servers can be connected by using multiple \`USE MCP\` commitments
6120
+ - The agent will have access to tools and resources provided by the MCP server
6121
+
6122
+ ## Example
6123
+
6124
+ \`\`\`book
6125
+ Company Lawyer
6126
+
6127
+ PERSONA You are a company lawyer.
6128
+ USE MCP http://legal-db.example.com
6129
+ \`\`\`
6130
+ `);
6131
+ }
6132
+ applyToAgentModelRequirements(requirements, content) {
6133
+ const mcpServerUrl = content.trim();
6134
+ if (!mcpServerUrl) {
6135
+ return requirements;
6136
+ }
6137
+ const existingMcpServers = requirements.mcpServers || [];
6138
+ // Avoid duplicates
6139
+ if (existingMcpServers.includes(mcpServerUrl)) {
6140
+ return requirements;
6141
+ }
6142
+ return {
6143
+ ...requirements,
6144
+ mcpServers: [...existingMcpServers, mcpServerUrl],
6145
+ };
6146
+ }
6147
+ }
6148
+ /**
6149
+ * Note: [💞] Ignore a discrepancy between file name and entity name
6150
+ */
6151
+
6152
+ /**
6153
+ * USE SEARCH ENGINE commitment definition
6154
+ *
6155
+ * The `USE SEARCH ENGINE` commitment indicates that the agent should utilize a search engine tool
6156
+ * to access and retrieve up-to-date information from the internet when necessary.
6157
+ *
6158
+ * The content following `USE SEARCH ENGINE` is an arbitrary text that the agent should know (e.g. search scope or instructions).
6159
+ *
6160
+ * Example usage in agent source:
6161
+ *
6162
+ * ```book
6163
+ * USE SEARCH ENGINE
6164
+ * USE SEARCH ENGINE Hledej informace o Přemyslovcích
6165
+ * ```
6166
+ *
6167
+ * @private [🪔] Maybe export the commitments through some package
6168
+ */
6169
+ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
6170
+ constructor() {
6171
+ super('USE SEARCH ENGINE', ['SEARCH ENGINE', 'SEARCH']);
6172
+ }
6173
+ /**
6174
+ * Short one-line description of USE SEARCH ENGINE.
6175
+ */
6176
+ get description() {
6177
+ return 'Enable the agent to use a search engine tool for accessing internet information.';
6178
+ }
6179
+ /**
6180
+ * Icon for this commitment.
6181
+ */
6182
+ get icon() {
6183
+ return '🔍';
6184
+ }
6185
+ /**
6186
+ * Markdown documentation for USE SEARCH ENGINE commitment.
6187
+ */
6188
+ get documentation() {
6189
+ return spaceTrim$1.spaceTrim(`
6190
+ # USE SEARCH ENGINE
6191
+
6192
+ Enables the agent to use a search engine tool to access and retrieve up-to-date information from the internet.
6193
+
6194
+ ## Key aspects
6195
+
6196
+ - The content following \`USE SEARCH ENGINE\` is an arbitrary text that the agent should know (e.g. search scope or instructions).
6197
+ - The actual search engine tool usage is handled by the agent runtime
6198
+ - Allows the agent to search for current information from the web
6199
+ - Useful for research tasks, finding facts, and accessing dynamic content
6200
+
6201
+ ## Examples
6202
+
6203
+ \`\`\`book
6204
+ Research Assistant
6205
+
6206
+ PERSONA You are a helpful research assistant specialized in finding current information
6207
+ USE SEARCH ENGINE
6208
+ RULE Always cite your sources when providing information from the web
6209
+ \`\`\`
6210
+
6211
+ \`\`\`book
6212
+ Fact Checker
6213
+
6214
+ PERSONA You are a fact checker
6215
+ USE SEARCH ENGINE
6216
+ ACTION Search for claims and verify them against reliable sources
6217
+ \`\`\`
6218
+ `);
6219
+ }
6220
+ applyToAgentModelRequirements(requirements, content) {
6221
+ // Get existing tools array or create new one
6222
+ const existingTools = requirements.tools || [];
6223
+ // Add 'web_search' to tools if not already present
6224
+ const updatedTools = existingTools.some((tool) => tool.name === 'web_search')
6225
+ ? existingTools
6226
+ : [
6227
+ ...existingTools,
6228
+ { type: 'web_search' },
6229
+ // <- Note: [🔰] This is just using simple native search tool by OpenAI @see https://platform.openai.com/docs/guides/tools-web-search
6230
+ // In future we will use proper MCP search tool:
6231
+ /*
6232
+
6233
+ {
6234
+ name: 'web_search',
6235
+ description: spaceTrim(`
6236
+ Search the internet for information.
6237
+ Use this tool when you need to find up-to-date information or facts that you don't know.
6238
+ ${!content ? '' : `Search scope / instructions: ${content}`}
6239
+ `),
6240
+ parameters: {
6241
+ type: 'object',
6242
+ properties: {
6243
+ query: {
6244
+ type: 'string',
6245
+ description: 'The search query',
6246
+ },
6247
+ },
6248
+ required: ['query'],
6249
+ },
6250
+ },
6251
+ */
6252
+ ];
6253
+ // Return requirements with updated tools and metadata
6254
+ return {
6255
+ ...requirements,
6256
+ tools: updatedTools,
6257
+ metadata: {
6258
+ ...requirements.metadata,
6259
+ useSearchEngine: content || true,
6260
+ },
6261
+ };
6262
+ }
6263
+ }
6264
+ /**
6265
+ * Note: [💞] Ignore a discrepancy between file name and entity name
6266
+ */
6267
+
6268
+ /**
6269
+ * USE TIME commitment definition
6270
+ *
6271
+ * The `USE TIME` commitment indicates that the agent should be able to determine the current date and time.
6272
+ *
6273
+ * Example usage in agent source:
6274
+ *
6275
+ * ```book
6276
+ * USE TIME
6277
+ * ```
6278
+ *
6279
+ * @private [🪔] Maybe export the commitments through some package
6280
+ */
6281
+ class UseTimeCommitmentDefinition extends BaseCommitmentDefinition {
6282
+ constructor() {
6283
+ super('USE TIME', ['CURRENT TIME', 'TIME', 'DATE']);
6284
+ }
6285
+ /**
6286
+ * Short one-line description of USE TIME.
6287
+ */
6288
+ get description() {
6289
+ return 'Enable the agent to determine the current date and time.';
6290
+ }
6291
+ /**
6292
+ * Icon for this commitment.
6293
+ */
6294
+ get icon() {
6295
+ return '🕒';
6296
+ }
6297
+ /**
6298
+ * Markdown documentation for USE TIME commitment.
6299
+ */
6300
+ get documentation() {
6301
+ return spaceTrim$1.spaceTrim(`
6302
+ # USE TIME
6303
+
6304
+ Enables the agent to determine the current date and time.
6305
+
6306
+ ## Key aspects
6307
+
6308
+ - This tool won't receive any input.
6309
+ - It outputs the current date and time as an ISO 8601 string.
6310
+ - Allows the agent to answer questions about the current time or date.
6311
+
6312
+ ## Examples
6313
+
6314
+ \`\`\`book
6315
+ Time-aware Assistant
6316
+
6317
+ PERSONA You are a helpful assistant who knows the current time.
6318
+ USE TIME
6319
+ \`\`\`
6320
+ `);
6321
+ }
6322
+ applyToAgentModelRequirements(requirements, content) {
6323
+ // Get existing tools array or create new one
6324
+ const existingTools = requirements.tools || [];
6325
+ // Add 'get_current_time' to tools if not already present
6326
+ const updatedTools = existingTools.some((tool) => tool.name === 'get_current_time')
6327
+ ? existingTools
6328
+ : [
6329
+ ...existingTools,
6330
+ {
6331
+ name: 'get_current_time',
6332
+ description: 'Get the current date and time in ISO 8601 format.',
6333
+ parameters: {
6334
+ type: 'object',
6335
+ properties: {
6336
+ timezone: {
6337
+ type: 'string',
6338
+ description: 'Optional timezone name (e.g. "Europe/Prague", "UTC", "America/New_York").',
6339
+ },
6340
+ },
6341
+ required: [],
6342
+ },
6343
+ },
6344
+ // <- TODO: !!!! define the function in LLM tools
6345
+ ];
6346
+ // Return requirements with updated tools and metadata
6347
+ return {
6348
+ ...requirements,
6349
+ tools: updatedTools,
6350
+ metadata: {
6351
+ ...requirements.metadata,
6352
+ },
6353
+ };
6354
+ }
6355
+ /**
6356
+ * Gets the `get_current_time` tool function implementation.
6357
+ */
6358
+ getToolFunctions() {
6359
+ return {
6360
+ async get_current_time(args) {
6361
+ var _a;
6362
+ console.log('!!!! [Tool] get_current_time called', { args });
6363
+ const { timezone } = args;
6364
+ if (!timezone) {
6365
+ return new Date().toISOString();
6366
+ }
6367
+ try {
6368
+ // Note: Returning ISO 8601 string but in the requested timezone
6369
+ const formatter = new Intl.DateTimeFormat('en-CA', {
6370
+ timeZone: timezone,
6371
+ year: 'numeric',
6372
+ month: '2-digit',
6373
+ day: '2-digit',
6374
+ hour: '2-digit',
6375
+ minute: '2-digit',
6376
+ second: '2-digit',
6377
+ hour12: false,
6378
+ timeZoneName: 'shortOffset',
6379
+ });
6380
+ const parts = formatter.formatToParts(new Date());
6381
+ const part = (type) => { var _a; return (_a = parts.find((p) => p.type === type)) === null || _a === void 0 ? void 0 : _a.value; };
6382
+ // en-CA format is YYYY-MM-DD
6383
+ 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', '')}`;
6384
+ return isoString;
6385
+ }
6386
+ catch (error) {
6387
+ // Fallback to UTC if timezone is invalid
6388
+ return new Date().toISOString();
6389
+ }
6390
+ },
6391
+ };
6392
+ }
6393
+ }
6394
+ /**
6395
+ * Note: [💞] Ignore a discrepancy between file name and entity name
6396
+ */
6397
+
6398
+ /**
6399
+ * Placeholder commitment definition for commitments that are not yet implemented
6400
+ *
6401
+ * This commitment simply adds its content 1:1 into the system message,
6402
+ * preserving the original behavior until proper implementation is added.
6403
+ *
6404
+ * @public exported from `@promptbook/core`
6405
+ */
6406
+ class NotYetImplementedCommitmentDefinition extends BaseCommitmentDefinition {
6407
+ constructor(type) {
6408
+ super(type);
6409
+ }
6410
+ /**
6411
+ * Short one-line description of a placeholder commitment.
6412
+ */
6413
+ get description() {
6414
+ return 'Placeholder commitment that appends content verbatim to the system message.';
6415
+ }
6416
+ /**
6417
+ * Icon for this commitment.
6418
+ */
6419
+ get icon() {
6420
+ return '🚧';
6421
+ }
6422
+ /**
6423
+ * Markdown documentation available at runtime.
6424
+ */
6425
+ get documentation() {
6426
+ return spaceTrim$1.spaceTrim(`
6427
+ # ${this.type}
6428
+
6429
+ This commitment is not yet fully implemented.
6430
+
6431
+ ## Key aspects
6432
+
6433
+ - Content is appended directly to the system message.
6434
+ - No special processing or validation is performed.
6435
+ - Behavior preserved until proper implementation is added.
6436
+
6437
+ ## Status
6438
+
6439
+ - **Status:** Placeholder implementation
6440
+ - **Effect:** Appends content prefixed by commitment type
6441
+ - **Future:** Will be replaced with specialized logic
6442
+
6443
+ ## Examples
6444
+
6445
+ \`\`\`book
6446
+ Example Agent
6447
+
6448
+ PERSONA You are a helpful assistant
6449
+ ${this.type} Your content here
6450
+ RULE Always be helpful
6451
+ \`\`\`
6452
+ `);
6453
+ }
6454
+ applyToAgentModelRequirements(requirements, content) {
6455
+ const trimmedContent = content.trim();
6456
+ if (!trimmedContent) {
6457
+ return requirements;
6458
+ }
6459
+ // Add the commitment content 1:1 to the system message
6460
+ const commitmentLine = `${this.type} ${trimmedContent}`;
6461
+ return this.appendToSystemMessage(requirements, commitmentLine, '\n\n');
6462
+ }
6463
+ }
6464
+
6465
+ /**
6466
+ * Registry of all available commitment definitions
6467
+ * This array contains instances of all commitment definitions
6468
+ * This is the single source of truth for all commitments in the system
6469
+ *
6470
+ * @private Use functions to access commitments instead of this array directly
6471
+ */
6472
+ const COMMITMENT_REGISTRY = [
6473
+ // Fully implemented commitments
6474
+ new PersonaCommitmentDefinition('PERSONA'),
6475
+ new PersonaCommitmentDefinition('PERSONAE'),
6476
+ new KnowledgeCommitmentDefinition(),
6477
+ new MemoryCommitmentDefinition('MEMORY'),
6478
+ new MemoryCommitmentDefinition('MEMORIES'),
6479
+ new StyleCommitmentDefinition('STYLE'),
6480
+ new StyleCommitmentDefinition('STYLES'),
6481
+ new RuleCommitmentDefinition('RULES'),
6482
+ new RuleCommitmentDefinition('RULE'),
6483
+ new LanguageCommitmentDefinition('LANGUAGES'),
6484
+ new LanguageCommitmentDefinition('LANGUAGE'),
6485
+ new SampleCommitmentDefinition('SAMPLE'),
6486
+ new SampleCommitmentDefinition('EXAMPLE'),
6487
+ new FormatCommitmentDefinition('FORMAT'),
6488
+ new FormatCommitmentDefinition('FORMATS'),
6489
+ new FromCommitmentDefinition('FROM'),
6490
+ new ImportCommitmentDefinition('IMPORT'),
6491
+ new ImportCommitmentDefinition('IMPORTS'),
6492
+ new ModelCommitmentDefinition('MODEL'),
6493
+ new ModelCommitmentDefinition('MODELS'),
6494
+ new ActionCommitmentDefinition('ACTION'),
6495
+ new ActionCommitmentDefinition('ACTIONS'),
6496
+ new ComponentCommitmentDefinition(),
6497
+ new MetaImageCommitmentDefinition(),
6498
+ new MetaColorCommitmentDefinition(),
6499
+ new MetaFontCommitmentDefinition(),
6500
+ new MetaLinkCommitmentDefinition(),
6501
+ new MetaCommitmentDefinition(),
6502
+ new NoteCommitmentDefinition('NOTE'),
6503
+ new NoteCommitmentDefinition('NOTES'),
6504
+ new NoteCommitmentDefinition('COMMENT'),
6505
+ new NoteCommitmentDefinition('NONCE'),
6506
+ new GoalCommitmentDefinition('GOAL'),
6507
+ new GoalCommitmentDefinition('GOALS'),
6508
+ new InitialMessageCommitmentDefinition(),
6509
+ new UserMessageCommitmentDefinition(),
6510
+ new AgentMessageCommitmentDefinition(),
6511
+ new MessageCommitmentDefinition('MESSAGE'),
6512
+ new MessageCommitmentDefinition('MESSAGES'),
6513
+ new ScenarioCommitmentDefinition('SCENARIO'),
6514
+ new ScenarioCommitmentDefinition('SCENARIOS'),
6515
+ new DeleteCommitmentDefinition('DELETE'),
6516
+ new DeleteCommitmentDefinition('CANCEL'),
6517
+ new DeleteCommitmentDefinition('DISCARD'),
6518
+ new DeleteCommitmentDefinition('REMOVE'),
6519
+ new DictionaryCommitmentDefinition(),
6520
+ new OpenCommitmentDefinition(),
6521
+ new ClosedCommitmentDefinition(),
6522
+ new UseBrowserCommitmentDefinition(),
6523
+ new UseSearchEngineCommitmentDefinition(),
6524
+ new UseTimeCommitmentDefinition(),
6525
+ new UseMcpCommitmentDefinition(),
6526
+ new UseCommitmentDefinition(),
6527
+ // Not yet implemented commitments (using placeholder)
6528
+ new NotYetImplementedCommitmentDefinition('EXPECT'),
6529
+ new NotYetImplementedCommitmentDefinition('BEHAVIOUR'),
6530
+ new NotYetImplementedCommitmentDefinition('BEHAVIOURS'),
6531
+ new NotYetImplementedCommitmentDefinition('AVOID'),
6532
+ new NotYetImplementedCommitmentDefinition('AVOIDANCE'),
6533
+ new NotYetImplementedCommitmentDefinition('CONTEXT'),
6534
+ ];
6535
+ /**
6536
+ * Gets all available commitment definitions
6537
+ * @returns Array of all commitment definitions
6538
+ *
6539
+ * @public exported from `@promptbook/core`
6540
+ */
6541
+ function getAllCommitmentDefinitions() {
6542
+ return $deepFreeze([...COMMITMENT_REGISTRY]);
6543
+ }
6544
+ /**
6545
+ * Gets all function implementations provided by all commitments
6546
+ *
6547
+ * @public exported from `@promptbook/core`
6548
+ */
6549
+ function getAllCommitmentsToolFunctions() {
6550
+ const allToolFunctions = {};
6551
+ for (const commitmentDefinition of getAllCommitmentDefinitions()) {
6552
+ const toolFunctions = commitmentDefinition.getToolFunctions();
6553
+ for (const [funcName, funcImpl] of Object.entries(toolFunctions)) {
6554
+ allToolFunctions[funcName] = funcImpl;
6555
+ }
6556
+ }
6557
+ return allToolFunctions;
6558
+ }
6559
+ /**
6560
+ * TODO: [🧠] Maybe create through standardized $register
6561
+ * Note: [💞] Ignore a discrepancy between file name and entity name
6562
+ */
6563
+
6564
+ /**
6565
+ * Extracts all code blocks from markdown.
6566
+ *
6567
+ * Note: There are multiple similar functions:
6568
+ * - `extractBlock` just extracts the content of the code block which is also used as built-in function for postprocessing
6569
+ * - `extractJsonBlock` extracts exactly one valid JSON code block
6570
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
6571
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
6572
+ *
6573
+ * @param markdown any valid markdown
6574
+ * @returns code blocks with language and content
6575
+ * @throws {ParseError} if block is not closed properly
6576
+ * @public exported from `@promptbook/markdown-utils`
6577
+ */
6578
+ function extractAllBlocksFromMarkdown(markdown) {
6579
+ const codeBlocks = [];
6580
+ const lines = markdown.split('\n');
6581
+ // Note: [0] Ensure that the last block notated by gt > will be closed
6582
+ lines.push('');
6583
+ let currentCodeBlock = null;
6584
+ for (const line of lines) {
6585
+ if (line.startsWith('> ') || line === '>') {
6586
+ if (currentCodeBlock === null) {
6587
+ currentCodeBlock = { blockNotation: '>', language: null, content: '' };
6588
+ } /* not else */
6589
+ if (currentCodeBlock.blockNotation === '>') {
6590
+ if (currentCodeBlock.content !== '') {
6591
+ currentCodeBlock.content += '\n';
6592
+ }
6593
+ currentCodeBlock.content += line.slice(2);
6594
+ }
6595
+ }
6596
+ else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '>' /* <- Note: [0] */) {
6597
+ codeBlocks.push(currentCodeBlock);
6598
+ currentCodeBlock = null;
6599
+ }
6600
+ /* not else */
6601
+ if (line.startsWith('```')) {
6602
+ const language = line.slice(3).trim() || null;
6603
+ if (currentCodeBlock === null) {
6604
+ currentCodeBlock = { blockNotation: '```', language, content: '' };
6605
+ }
6606
+ else {
6607
+ if (language !== null) {
6608
+ throw new ParseError(`${capitalize(currentCodeBlock.language || 'the')} code block was not closed and already opening new ${language} code block`);
6609
+ }
6610
+ codeBlocks.push(currentCodeBlock);
6611
+ currentCodeBlock = null;
6612
+ }
6613
+ }
6614
+ else if (currentCodeBlock !== null && currentCodeBlock.blockNotation === '```') {
6615
+ if (currentCodeBlock.content !== '') {
6616
+ currentCodeBlock.content += '\n';
6617
+ }
6618
+ currentCodeBlock.content += line.split('\\`\\`\\`').join('```') /* <- TODO: Maybe make proper unescape */;
6619
+ }
6620
+ }
6621
+ if (currentCodeBlock !== null) {
6622
+ throw new ParseError(`${capitalize(currentCodeBlock.language || 'the')} code block was not closed at the end of the markdown`);
6623
+ }
6624
+ return codeBlocks;
6625
+ }
6626
+ /**
6627
+ * TODO: Maybe name for `blockNotation` instead of '```' and '>'
6628
+ */
6629
+
6630
+ /**
6631
+ * Extracts exactly ONE code block from markdown.
6632
+ *
6633
+ * - When there are multiple or no code blocks the function throws a `ParseError`
6634
+ *
6635
+ * Note: There are multiple similar functions:
6636
+ * - `extractBlock` just extracts the content of the code block which is also used as built-in function for postprocessing
6637
+ * - `extractJsonBlock` extracts exactly one valid JSON code block
6638
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
6639
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
6640
+ *
6641
+ * @param markdown any valid markdown
6642
+ * @returns code block with language and content
6643
+ * @public exported from `@promptbook/markdown-utils`
6644
+ * @throws {ParseError} if there is not exactly one code block in the markdown
6645
+ */
6646
+ function extractOneBlockFromMarkdown(markdown) {
6647
+ const codeBlocks = extractAllBlocksFromMarkdown(markdown);
6648
+ if (codeBlocks.length !== 1) {
6649
+ throw new ParseError(spaceTrim__default["default"]((block) => `
6650
+ There should be exactly 1 code block in task section, found ${codeBlocks.length} code blocks
6651
+
6652
+ ${block(codeBlocks.map((block, i) => `Block ${i + 1}:\n${block.content}`).join('\n\n\n'))}
6653
+ `));
6654
+ }
6655
+ return codeBlocks[0];
6656
+ }
6657
+ /***
6658
+ * TODO: [🍓][🌻] Decide of this is internal utility, external util OR validator/postprocessor
6659
+ */
6660
+
6661
+ /**
6662
+ * Extracts code block from markdown.
6663
+ *
6664
+ * - When there are multiple or no code blocks the function throws a `ParseError`
6665
+ *
6666
+ * Note: There are multiple similar function:
6667
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
6668
+ * - `extractJsonBlock` extracts exactly one valid JSON code block
6669
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
6670
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
6671
+ *
6672
+ * @public exported from `@promptbook/markdown-utils`
6673
+ * @throws {ParseError} if there is not exactly one code block in the markdown
6674
+ */
6675
+ function extractBlock(markdown) {
6676
+ const { content } = extractOneBlockFromMarkdown(markdown);
6677
+ return content;
6678
+ }
6679
+
6680
+ /**
6681
+ * Prettify the html code
6682
+ *
6683
+ * @param content raw html code
6684
+ * @returns formatted html code
6685
+ * @private withing the package because of HUGE size of prettier dependency
6686
+ * @deprecated Prettier removed from Promptbook due to package size
6687
+ */
6688
+ function prettifyMarkdown(content) {
6689
+ return (content + `\n\n<!-- Note: Prettier removed from Promptbook -->`);
6690
+ }
6691
+
6692
+ /**
6693
+ * Function trimCodeBlock will trim starting and ending code block from the string if it is present.
6694
+ *
6695
+ * Note: [🔂] This function is idempotent.
6696
+ * Note: This is useful for post-processing of the result of the chat LLM model
6697
+ * when the model wraps the result in the (markdown) code block.
6698
+ *
6699
+ * @public exported from `@promptbook/markdown-utils`
6700
+ */
6701
+ function trimCodeBlock(value) {
6702
+ value = spaceTrim$1.spaceTrim(value);
6703
+ if (!/^```[a-z]*(.*)```$/is.test(value)) {
6704
+ return value;
6705
+ }
6706
+ value = value.replace(/^```[a-z]*/i, '');
6707
+ value = value.replace(/```$/i, '');
6708
+ value = spaceTrim$1.spaceTrim(value);
6709
+ return value;
6710
+ }
6711
+
6712
+ /**
6713
+ * Function trimEndOfCodeBlock will remove ending code block from the string if it is present.
6714
+ *
6715
+ * Note: This is useful for post-processing of the result of the completion LLM model
6716
+ * if you want to start code block in the prompt but you don't want to end it in the result.
6717
+ *
6718
+ * @public exported from `@promptbook/markdown-utils`
6719
+ */
6720
+ function trimEndOfCodeBlock(value) {
6721
+ value = spaceTrim$1.spaceTrim(value);
6722
+ value = value.replace(/```$/g, '');
6723
+ value = spaceTrim$1.spaceTrim(value);
6724
+ return value;
6725
+ }
6726
+
6727
+ /**
6728
+ * @private internal for `preserve`
6729
+ */
6730
+ const _preserved = [];
6731
+ /**
6732
+ * Does nothing, but preserves the function in the bundle
6733
+ * Compiler is tricked into thinking the function is used
6734
+ *
6735
+ * @param value any function to preserve
6736
+ * @returns nothing
6737
+ * @private within the repository
6738
+ */
6739
+ function $preserve(...value) {
6740
+ _preserved.push(...value);
6741
+ }
6742
+ /**
6743
+ * Note: [💞] Ignore a discrepancy between file name and entity name
6744
+ */
6745
+
6746
+ // Note: [💎]
6747
+ /**
6748
+ * ScriptExecutionTools for JavaScript implemented via eval
6749
+ *
6750
+ * Warning: It is used for testing and mocking
2929
6751
  * **NOT intended to use in the production** due to its unsafe nature, use `JavascriptExecutionTools` instead.
2930
6752
  *
2931
6753
  * @public exported from `@promptbook/javascript`
@@ -3028,6 +6850,13 @@
3028
6850
  `const ${functionName} = buildinFunctions.${functionName};`)
3029
6851
  .join('\n');
3030
6852
  // TODO: DRY [🍯]
6853
+ const commitmentsFunctions = getAllCommitmentsToolFunctions();
6854
+ const commitmentsFunctionsStatement = Object.keys(commitmentsFunctions)
6855
+ .map((functionName) =>
6856
+ // Note: Custom functions are exposed to the current scope as variables
6857
+ `const ${functionName} = commitmentsFunctions.${functionName};`)
6858
+ .join('\n');
6859
+ // TODO: DRY [🍯]
3031
6860
  const customFunctions = this.options.functions || {};
3032
6861
  const customFunctionsStatement = Object.keys(customFunctions)
3033
6862
  .map((functionName) =>
@@ -3041,6 +6870,10 @@
3041
6870
  // Build-in functions:
3042
6871
  ${block(buildinFunctionsStatement)}
3043
6872
 
6873
+ // Commitments functions:
6874
+ ${block(commitmentsFunctionsStatement)}
6875
+
6876
+
3044
6877
  // Custom functions:
3045
6878
  ${block(customFunctionsStatement || '// -- No custom functions --')}
3046
6879
 
@@ -3048,7 +6881,7 @@
3048
6881
  ${block(Object.entries(parameters)
3049
6882
  .map(([key, value]) => `const ${key} = ${JSON.stringify(value)};`)
3050
6883
  .join('\n'))}
3051
- (()=>{ ${script} })()
6884
+ (async ()=>{ ${script} })()
3052
6885
  `);
3053
6886
  if (this.options.isVerbose) {
3054
6887
  console.info(spaceTrim__default["default"]((block) => `