@promptbook/javascript 0.105.0-21 → 0.105.0-26

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