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