@promptbook/fake-llm 0.105.0-21 → 0.105.0-23

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