@promptbook/browser 0.114.0-3 → 0.114.0-4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/README.md +1 -9
  2. package/esm/index.es.js +504 -4004
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/src/book-2.0/agent-source/AgentBasicInformation.d.ts +3 -3
  5. package/esm/src/cli/cli-commands/coder/boilerplateCount.d.ts +52 -0
  6. package/esm/src/cli/cli-commands/coder/generate-boilerplates.d.ts +3 -2
  7. package/esm/src/commitments/{COMPONENT/COMPONENT.d.ts → META_FULLNAME/META_FULLNAME.d.ts} +8 -5
  8. package/esm/src/commitments/META_ID/META_ID.d.ts +32 -0
  9. package/esm/src/commitments/index.d.ts +4 -12
  10. package/esm/src/llm-providers/agent/Agent.d.ts +1 -1
  11. package/esm/src/llm-providers/openai/OpenAiAgentKitExecutionToolsToolBuilder.d.ts +1 -1
  12. package/esm/src/{commitments/USE_BROWSER → scrapers/_common/utils}/fetchUrlContent.d.ts +2 -3
  13. package/esm/src/version.d.ts +1 -1
  14. package/package.json +2 -3
  15. package/umd/index.umd.js +508 -4008
  16. package/umd/index.umd.js.map +1 -1
  17. package/umd/src/book-2.0/agent-source/AgentBasicInformation.d.ts +3 -3
  18. package/umd/src/cli/cli-commands/coder/boilerplateCount.d.ts +52 -0
  19. package/umd/src/cli/cli-commands/coder/generate-boilerplates.d.ts +3 -2
  20. package/umd/src/commitments/{COMPONENT/COMPONENT.d.ts → META_FULLNAME/META_FULLNAME.d.ts} +8 -5
  21. package/umd/src/commitments/META_ID/META_ID.d.ts +32 -0
  22. package/umd/src/commitments/index.d.ts +4 -12
  23. package/umd/src/llm-providers/agent/Agent.d.ts +1 -1
  24. package/umd/src/llm-providers/openai/OpenAiAgentKitExecutionToolsToolBuilder.d.ts +1 -1
  25. package/umd/src/{commitments/USE_BROWSER → scrapers/_common/utils}/fetchUrlContent.d.ts +2 -3
  26. package/umd/src/version.d.ts +1 -1
  27. package/esm/src/commitments/MEMORY/MEMORY.d.ts +0 -48
  28. package/esm/src/commitments/MEMORY/MemoryToolNames.d.ts +0 -11
  29. package/esm/src/commitments/MEMORY/MemoryToolRuntimeAdapter.d.ts +0 -149
  30. package/esm/src/commitments/MEMORY/createMemorySystemMessage.d.ts +0 -6
  31. package/esm/src/commitments/MEMORY/createMemoryToolFunctions.d.ts +0 -8
  32. package/esm/src/commitments/MEMORY/createMemoryTools.d.ts +0 -14
  33. package/esm/src/commitments/MEMORY/getMemoryCommitmentDocumentation.d.ts +0 -6
  34. package/esm/src/commitments/MEMORY/getMemoryToolRuntimeAdapterOrDisabledResult.d.ts +0 -17
  35. package/esm/src/commitments/MEMORY/getMemoryToolTitles.d.ts +0 -7
  36. package/esm/src/commitments/MEMORY/parseMemoryToolArgs.d.ts +0 -61
  37. package/esm/src/commitments/MEMORY/resolveMemoryRuntimeContext.d.ts +0 -8
  38. package/esm/src/commitments/MEMORY/setMemoryToolRuntimeAdapter.d.ts +0 -13
  39. package/esm/src/commitments/META/META.d.ts +0 -65
  40. package/esm/src/commitments/USE/aggregateUseCommitmentSystemMessages.d.ts +0 -32
  41. package/esm/src/commitments/USE_BROWSER/USE_BROWSER.d.ts +0 -58
  42. package/esm/src/commitments/USE_BROWSER/fetchUrlContentViaBrowser.d.ts +0 -13
  43. package/esm/src/commitments/USE_BROWSER/resolveRunBrowserToolForNode.d.ts +0 -10
  44. package/esm/src/commitments/USE_DEEPSEARCH/USE_DEEPSEARCH.d.ts +0 -47
  45. package/esm/src/commitments/USE_EMAIL/USE_EMAIL.d.ts +0 -38
  46. package/esm/src/commitments/USE_EMAIL/parseUseEmailCommitmentContent.d.ts +0 -21
  47. package/esm/src/commitments/USE_EMAIL/parseUseEmailCommitmentContent.test.d.ts +0 -1
  48. package/esm/src/commitments/USE_EMAIL/resolveSendEmailToolForNode.d.ts +0 -11
  49. package/esm/src/commitments/USE_EMAIL/sendEmailViaBrowser.d.ts +0 -13
  50. package/esm/src/commitments/USE_SEARCH_ENGINE/USE_SEARCH_ENGINE.d.ts +0 -46
  51. package/esm/src/commitments/USE_SEARCH_ENGINE/USE_SEARCH_ENGINE.test.d.ts +0 -1
  52. package/esm/src/commitments/USE_SPAWN/USE_SPAWN.d.ts +0 -38
  53. package/esm/src/commitments/USE_SPAWN/USE_SPAWN.test.d.ts +0 -1
  54. package/esm/src/commitments/USE_SPAWN/resolveSpawnAgentToolForNode.d.ts +0 -9
  55. package/esm/src/commitments/USE_SPAWN/spawnAgentViaBrowser.d.ts +0 -12
  56. package/esm/src/commitments/USE_TIME/USE_TIME.d.ts +0 -43
  57. package/esm/src/commitments/USE_TIME/USE_TIME.test.d.ts +0 -1
  58. package/esm/src/commitments/USE_TIMEOUT/TimeoutToolNames.d.ts +0 -11
  59. package/esm/src/commitments/USE_TIMEOUT/TimeoutToolRuntimeAdapter.d.ts +0 -212
  60. package/esm/src/commitments/USE_TIMEOUT/USE_TIMEOUT.d.ts +0 -38
  61. package/esm/src/commitments/USE_TIMEOUT/USE_TIMEOUT.test.d.ts +0 -1
  62. package/esm/src/commitments/USE_TIMEOUT/createTimeoutSystemMessage.d.ts +0 -6
  63. package/esm/src/commitments/USE_TIMEOUT/createTimeoutToolFunctions.d.ts +0 -8
  64. package/esm/src/commitments/USE_TIMEOUT/createTimeoutTools.d.ts +0 -7
  65. package/esm/src/commitments/USE_TIMEOUT/getTimeoutToolRuntimeAdapterOrDisabledResult.d.ts +0 -17
  66. package/esm/src/commitments/USE_TIMEOUT/parseTimeoutToolArgs.d.ts +0 -78
  67. package/esm/src/commitments/USE_TIMEOUT/resolveTimeoutRuntimeContext.d.ts +0 -8
  68. package/esm/src/commitments/USE_TIMEOUT/setTimeoutToolRuntimeAdapter.d.ts +0 -13
  69. package/esm/src/commitments/WALLET/WALLET.d.ts +0 -21
  70. package/esm/src/commitments/WALLET/WALLET.test.d.ts +0 -1
  71. package/esm/src/commitments/WALLET/WalletToolNames.d.ts +0 -12
  72. package/esm/src/commitments/WALLET/WalletToolRuntimeAdapter.d.ts +0 -163
  73. package/esm/src/commitments/WALLET/createWalletSystemMessage.d.ts +0 -6
  74. package/esm/src/commitments/WALLET/createWalletToolFunctions.d.ts +0 -8
  75. package/esm/src/commitments/WALLET/createWalletTools.d.ts +0 -7
  76. package/esm/src/commitments/WALLET/getWalletCommitmentDocumentation.d.ts +0 -6
  77. package/esm/src/commitments/WALLET/getWalletToolRuntimeAdapterOrDisabledResult.d.ts +0 -16
  78. package/esm/src/commitments/WALLET/getWalletToolTitles.d.ts +0 -7
  79. package/esm/src/commitments/WALLET/parseWalletToolArgs.d.ts +0 -51
  80. package/esm/src/commitments/WALLET/resolveWalletRuntimeContext.d.ts +0 -8
  81. package/esm/src/commitments/WALLET/setWalletToolRuntimeAdapter.d.ts +0 -13
  82. package/esm/src/commitments/_common/createSerpSearchToolFunction.d.ts +0 -12
  83. package/umd/src/book-2.0/agent-source/createAgentModelRequirements.useCommitmentAggregation.test.d.ts +0 -1
  84. package/umd/src/commitments/MEMORY/MEMORY.d.ts +0 -48
  85. package/umd/src/commitments/MEMORY/MEMORY.test.d.ts +0 -1
  86. package/umd/src/commitments/MEMORY/MemoryToolNames.d.ts +0 -11
  87. package/umd/src/commitments/MEMORY/MemoryToolRuntimeAdapter.d.ts +0 -149
  88. package/umd/src/commitments/MEMORY/createMemorySystemMessage.d.ts +0 -6
  89. package/umd/src/commitments/MEMORY/createMemoryToolFunctions.d.ts +0 -8
  90. package/umd/src/commitments/MEMORY/createMemoryTools.d.ts +0 -14
  91. package/umd/src/commitments/MEMORY/getMemoryCommitmentDocumentation.d.ts +0 -6
  92. package/umd/src/commitments/MEMORY/getMemoryToolRuntimeAdapterOrDisabledResult.d.ts +0 -17
  93. package/umd/src/commitments/MEMORY/getMemoryToolTitles.d.ts +0 -7
  94. package/umd/src/commitments/MEMORY/parseMemoryToolArgs.d.ts +0 -61
  95. package/umd/src/commitments/MEMORY/resolveMemoryRuntimeContext.d.ts +0 -8
  96. package/umd/src/commitments/MEMORY/setMemoryToolRuntimeAdapter.d.ts +0 -13
  97. package/umd/src/commitments/META/META.d.ts +0 -65
  98. package/umd/src/commitments/USE/aggregateUseCommitmentSystemMessages.d.ts +0 -32
  99. package/umd/src/commitments/USE_BROWSER/USE_BROWSER.d.ts +0 -58
  100. package/umd/src/commitments/USE_BROWSER/USE_BROWSER.test.d.ts +0 -1
  101. package/umd/src/commitments/USE_BROWSER/fetchUrlContentViaBrowser.d.ts +0 -13
  102. package/umd/src/commitments/USE_BROWSER/resolveRunBrowserToolForNode.d.ts +0 -10
  103. package/umd/src/commitments/USE_BROWSER/resolveRunBrowserToolForNode.test.d.ts +0 -1
  104. package/umd/src/commitments/USE_DEEPSEARCH/USE_DEEPSEARCH.d.ts +0 -47
  105. package/umd/src/commitments/USE_DEEPSEARCH/USE_DEEPSEARCH.test.d.ts +0 -1
  106. package/umd/src/commitments/USE_EMAIL/USE_EMAIL.d.ts +0 -38
  107. package/umd/src/commitments/USE_EMAIL/USE_EMAIL.test.d.ts +0 -1
  108. package/umd/src/commitments/USE_EMAIL/parseUseEmailCommitmentContent.d.ts +0 -21
  109. package/umd/src/commitments/USE_EMAIL/parseUseEmailCommitmentContent.test.d.ts +0 -1
  110. package/umd/src/commitments/USE_EMAIL/resolveSendEmailToolForNode.d.ts +0 -11
  111. package/umd/src/commitments/USE_EMAIL/sendEmailViaBrowser.d.ts +0 -13
  112. package/umd/src/commitments/USE_SEARCH_ENGINE/USE_SEARCH_ENGINE.d.ts +0 -46
  113. package/umd/src/commitments/USE_SEARCH_ENGINE/USE_SEARCH_ENGINE.test.d.ts +0 -1
  114. package/umd/src/commitments/USE_SPAWN/USE_SPAWN.d.ts +0 -38
  115. package/umd/src/commitments/USE_SPAWN/USE_SPAWN.test.d.ts +0 -1
  116. package/umd/src/commitments/USE_SPAWN/resolveSpawnAgentToolForNode.d.ts +0 -9
  117. package/umd/src/commitments/USE_SPAWN/spawnAgentViaBrowser.d.ts +0 -12
  118. package/umd/src/commitments/USE_TIME/USE_TIME.d.ts +0 -43
  119. package/umd/src/commitments/USE_TIME/USE_TIME.test.d.ts +0 -1
  120. package/umd/src/commitments/USE_TIMEOUT/TimeoutToolNames.d.ts +0 -11
  121. package/umd/src/commitments/USE_TIMEOUT/TimeoutToolRuntimeAdapter.d.ts +0 -212
  122. package/umd/src/commitments/USE_TIMEOUT/USE_TIMEOUT.d.ts +0 -38
  123. package/umd/src/commitments/USE_TIMEOUT/USE_TIMEOUT.test.d.ts +0 -1
  124. package/umd/src/commitments/USE_TIMEOUT/createTimeoutSystemMessage.d.ts +0 -6
  125. package/umd/src/commitments/USE_TIMEOUT/createTimeoutToolFunctions.d.ts +0 -8
  126. package/umd/src/commitments/USE_TIMEOUT/createTimeoutTools.d.ts +0 -7
  127. package/umd/src/commitments/USE_TIMEOUT/getTimeoutToolRuntimeAdapterOrDisabledResult.d.ts +0 -17
  128. package/umd/src/commitments/USE_TIMEOUT/parseTimeoutToolArgs.d.ts +0 -78
  129. package/umd/src/commitments/USE_TIMEOUT/resolveTimeoutRuntimeContext.d.ts +0 -8
  130. package/umd/src/commitments/USE_TIMEOUT/setTimeoutToolRuntimeAdapter.d.ts +0 -13
  131. package/umd/src/commitments/WALLET/WALLET.d.ts +0 -21
  132. package/umd/src/commitments/WALLET/WALLET.test.d.ts +0 -1
  133. package/umd/src/commitments/WALLET/WalletToolNames.d.ts +0 -12
  134. package/umd/src/commitments/WALLET/WalletToolRuntimeAdapter.d.ts +0 -163
  135. package/umd/src/commitments/WALLET/createWalletSystemMessage.d.ts +0 -6
  136. package/umd/src/commitments/WALLET/createWalletToolFunctions.d.ts +0 -8
  137. package/umd/src/commitments/WALLET/createWalletTools.d.ts +0 -7
  138. package/umd/src/commitments/WALLET/getWalletCommitmentDocumentation.d.ts +0 -6
  139. package/umd/src/commitments/WALLET/getWalletToolRuntimeAdapterOrDisabledResult.d.ts +0 -16
  140. package/umd/src/commitments/WALLET/getWalletToolTitles.d.ts +0 -7
  141. package/umd/src/commitments/WALLET/parseWalletToolArgs.d.ts +0 -51
  142. package/umd/src/commitments/WALLET/resolveWalletRuntimeContext.d.ts +0 -8
  143. package/umd/src/commitments/WALLET/setWalletToolRuntimeAdapter.d.ts +0 -13
  144. package/umd/src/commitments/_common/createSerpSearchToolFunction.d.ts +0 -12
  145. /package/esm/src/book-2.0/agent-source/{createAgentModelRequirements.useCommitmentAggregation.test.d.ts → createAgentModelRequirements.commitmentAggregation.test.d.ts} +0 -0
  146. /package/esm/src/{commitments/MEMORY/MEMORY.test.d.ts → cli/cli-commands/coder/boilerplateCount.test.d.ts} +0 -0
  147. /package/esm/src/{commitments/USE_BROWSER/USE_BROWSER.test.d.ts → cli/cli-commands/coder/generate-boilerplates.test.d.ts} +0 -0
  148. /package/esm/src/commitments/{META → META_DESCRIPTION}/META_DESCRIPTION.d.ts +0 -0
  149. /package/{esm/src/commitments/USE_BROWSER/resolveRunBrowserToolForNode.test.d.ts → umd/src/book-2.0/agent-source/createAgentModelRequirements.commitmentAggregation.test.d.ts} +0 -0
  150. /package/{esm/src/commitments/USE_DEEPSEARCH/USE_DEEPSEARCH.test.d.ts → umd/src/cli/cli-commands/coder/boilerplateCount.test.d.ts} +0 -0
  151. /package/{esm/src/commitments/USE_EMAIL/USE_EMAIL.test.d.ts → umd/src/cli/cli-commands/coder/generate-boilerplates.test.d.ts} +0 -0
  152. /package/umd/src/commitments/{META → META_DESCRIPTION}/META_DESCRIPTION.d.ts +0 -0
package/umd/index.umd.js CHANGED
@@ -1,14 +1,13 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('spacetrim'), require('destroyable'), require('rxjs'), require('crypto-js'), require('crypto-js/enc-hex'), require('path'), require('crypto'), require('moment'), require('mime-types'), require('waitasecond'), require('crypto-js/sha256'), require('papaparse'), require('colors'), require('bottleneck')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'spacetrim', 'destroyable', 'rxjs', 'crypto-js', 'crypto-js/enc-hex', 'path', 'crypto', 'moment', 'mime-types', 'waitasecond', 'crypto-js/sha256', 'papaparse', 'colors', 'bottleneck'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-browser"] = {}, global.spacetrim, global.destroyable, global.rxjs, global.CryptoJS, global.hexEncoder, global.path, null, global.moment, global.mimeTypes, global.waitasecond, global.sha256, global.papaparse, global.colors, global.Bottleneck));
5
- })(this, (function (exports, spacetrim, destroyable, rxjs, CryptoJS, hexEncoder, path, crypto, moment, mimeTypes, waitasecond, sha256, papaparse, colors, Bottleneck) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('spacetrim'), require('destroyable'), require('rxjs'), require('crypto-js'), require('crypto-js/enc-hex'), require('path'), require('crypto'), require('mime-types'), require('waitasecond'), require('crypto-js/sha256'), require('papaparse'), require('colors'), require('bottleneck')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'spacetrim', 'destroyable', 'rxjs', 'crypto-js', 'crypto-js/enc-hex', 'path', 'crypto', 'mime-types', 'waitasecond', 'crypto-js/sha256', 'papaparse', 'colors', 'bottleneck'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-browser"] = {}, global.spacetrim, global.destroyable, global.rxjs, global.CryptoJS, global.hexEncoder, global.path, null, global.mimeTypes, global.waitasecond, global.sha256, global.papaparse, global.colors, global.Bottleneck));
5
+ })(this, (function (exports, spacetrim, destroyable, rxjs, CryptoJS, hexEncoder, path, crypto, mimeTypes, waitasecond, sha256, papaparse, colors, Bottleneck) { '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 CryptoJS__default = /*#__PURE__*/_interopDefaultLegacy(CryptoJS);
10
10
  var hexEncoder__default = /*#__PURE__*/_interopDefaultLegacy(hexEncoder);
11
- var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
12
11
  var sha256__default = /*#__PURE__*/_interopDefaultLegacy(sha256);
13
12
  var papaparse__default = /*#__PURE__*/_interopDefaultLegacy(papaparse);
14
13
  var colors__default = /*#__PURE__*/_interopDefaultLegacy(colors);
@@ -28,7 +27,7 @@
28
27
  * @generated
29
28
  * @see https://github.com/webgptorg/promptbook
30
29
  */
31
- const PROMPTBOOK_ENGINE_VERSION = '0.114.0-3';
30
+ const PROMPTBOOK_ENGINE_VERSION = '0.114.0-4';
32
31
  /**
33
32
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
34
33
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -1673,7 +1672,7 @@
1673
1672
  Research Assistant
1674
1673
 
1675
1674
  PERSONA You are a helpful research assistant
1676
- USE SEARCH ENGINE
1675
+ USE MCP https://mcp.example.com/server
1677
1676
  RULE Always cite your sources when providing information from the web
1678
1677
  \`\`\`
1679
1678
 
@@ -1693,8 +1692,8 @@
1693
1692
  Code Assistant
1694
1693
 
1695
1694
  PERSONA You are a programming assistant
1696
- USE BROWSER
1697
- USE SEARCH ENGINE
1695
+ USE PROJECT https://github.com/example/project
1696
+ USE MCP https://mcp.example.com/server
1698
1697
  RULE Prefer the narrowest useful capability for the task.
1699
1698
  \`\`\`
1700
1699
  `);
@@ -1795,65 +1794,6 @@
1795
1794
  }
1796
1795
  // Note: [💞] Ignore a discrepancy between file name and entity name
1797
1796
 
1798
- /**
1799
- * COMPONENT commitment definition
1800
- *
1801
- * The COMPONENT commitment defines a UI component that the agent can render in the chat.
1802
- *
1803
- * @private [🪔] Maybe export the commitments through some package
1804
- */
1805
- class ComponentCommitmentDefinition extends BaseCommitmentDefinition {
1806
- constructor() {
1807
- super('COMPONENT');
1808
- }
1809
- /**
1810
- * Short one-line description of COMPONENT.
1811
- */
1812
- get description() {
1813
- return 'Define a UI component that the agent can render in the chat.';
1814
- }
1815
- /**
1816
- * Icon for this commitment.
1817
- */
1818
- get icon() {
1819
- return '🧩';
1820
- }
1821
- /**
1822
- * Markdown documentation for COMPONENT commitment.
1823
- */
1824
- get documentation() {
1825
- return spacetrim.spaceTrim(`
1826
- # COMPONENT
1827
-
1828
- Defines a UI component that the agent can render in the chat.
1829
-
1830
- ## Key aspects
1831
-
1832
- - Tells the agent that a specific component is available.
1833
- - Provides syntax for using the component.
1834
-
1835
- ## Example
1836
-
1837
- \`\`\`book
1838
- COMPONENT Arrow
1839
- The agent should render an arrow component in the chat UI.
1840
- Syntax:
1841
- <Arrow direction="up" color="red" />
1842
- \`\`\`
1843
- `);
1844
- }
1845
- applyToAgentModelRequirements(requirements, content) {
1846
- const trimmedContent = content.trim();
1847
- if (!trimmedContent) {
1848
- return requirements;
1849
- }
1850
- // Add component capability to the system message
1851
- const componentSection = `Component: ${trimmedContent}`;
1852
- return this.appendToSystemMessage(requirements, componentSection, '\n\n');
1853
- }
1854
- }
1855
- // Note: [💞] Ignore a discrepancy between file name and entity name
1856
-
1857
1797
  /**
1858
1798
  * DELETE commitment definition
1859
1799
  *
@@ -3705,653 +3645,6 @@
3705
3645
  }
3706
3646
  // Note: [💞] Ignore a discrepancy between file name and entity name
3707
3647
 
3708
- /**
3709
- * @@@
3710
- *
3711
- * @private utility for commitments
3712
- */
3713
- function formatOptionalInstructionBlock(label, content) {
3714
- const trimmedContent = spacetrim.spaceTrim(content);
3715
- if (!trimmedContent) {
3716
- return '';
3717
- }
3718
- return spacetrim.spaceTrim((block) => `
3719
- - ${label}:
3720
- ${block(trimmedContent
3721
- .split(/\r?\n/)
3722
- .map((line) => `- ${line}`)
3723
- .join('\n'))}
3724
- `);
3725
- }
3726
-
3727
- /**
3728
- * Names of tools used by the MEMORY commitment.
3729
- *
3730
- * @private function of MemoryCommitmentDefinition
3731
- */
3732
- const MemoryToolNames = {
3733
- retrieve: 'retrieve_user_memory',
3734
- store: 'store_user_memory',
3735
- update: 'update_user_memory',
3736
- delete: 'delete_user_memory',
3737
- };
3738
-
3739
- /**
3740
- * Builds the MEMORY instruction block appended to the system message.
3741
- *
3742
- * @private function of MemoryCommitmentDefinition
3743
- */
3744
- function createMemorySystemMessage(extraInstructions) {
3745
- return spacetrim.spaceTrim((block) => `
3746
- ## Memory
3747
-
3748
- - Prefer storing agent-scoped memories; only make them global when the fact should apply across all your agents.
3749
- - You can use persistent user memory tools.
3750
- - Use \`${MemoryToolNames.retrieve}\` to load relevant memory before answering.
3751
- - Use \`${MemoryToolNames.store}\` to save stable user-specific facts that improve future help.
3752
- - Use \`${MemoryToolNames.update}\` to refresh an existing memory when the content changes.
3753
- - Use \`${MemoryToolNames.delete}\` to delete memories that are no longer accurate (deletions are soft and hidden from future queries).
3754
- - Store concise memory items and avoid duplicates.
3755
- - Never claim memory was saved or loaded unless the tool confirms it.
3756
- ${block(extraInstructions)}
3757
- `);
3758
- }
3759
-
3760
- /**
3761
- * Builds a disabled memory-tool response payload.
3762
- *
3763
- * @private function of MemoryCommitmentDefinition
3764
- */
3765
- function createDisabledMemoryResult(action, message) {
3766
- if (action === 'retrieve') {
3767
- return {
3768
- action,
3769
- status: 'disabled',
3770
- memories: [],
3771
- message,
3772
- };
3773
- }
3774
- if (action === 'store') {
3775
- return {
3776
- action,
3777
- status: 'disabled',
3778
- message,
3779
- };
3780
- }
3781
- if (action === 'update') {
3782
- return {
3783
- action,
3784
- status: 'disabled',
3785
- message,
3786
- };
3787
- }
3788
- if (action === 'delete') {
3789
- return {
3790
- action,
3791
- status: 'disabled',
3792
- message,
3793
- };
3794
- }
3795
- throw new Error(`Unsupported memory tool action: ${action}`);
3796
- }
3797
- /**
3798
- * Gets the runtime adapter and returns a disabled result when unavailable.
3799
- *
3800
- * @private function of MemoryCommitmentDefinition
3801
- */
3802
- function getMemoryToolRuntimeAdapterOrDisabledResult(action, runtimeContext) {
3803
- if (!runtimeContext.enabled || runtimeContext.isTeamConversation || runtimeContext.isPrivateMode) {
3804
- const message = runtimeContext.isPrivateMode
3805
- ? 'Memory is disabled because private mode is active.'
3806
- : runtimeContext.isTeamConversation
3807
- ? 'Memory is disabled for TEAM conversations.'
3808
- : 'Memory is disabled for unauthenticated users.';
3809
- return {
3810
- adapter: null,
3811
- disabledResult: createDisabledMemoryResult(action, message),
3812
- };
3813
- }
3814
- {
3815
- return {
3816
- adapter: null,
3817
- disabledResult: createDisabledMemoryResult(action, 'Memory runtime is not available in this environment.'),
3818
- };
3819
- }
3820
- }
3821
-
3822
- /**
3823
- * Parses a memory identifier argument shared across MEMORY tools.
3824
- *
3825
- * @private function of MemoryCommitmentDefinition
3826
- */
3827
- function parseMemoryIdArg(value) {
3828
- const memoryId = typeof value === 'string' ? value.trim() : '';
3829
- if (!memoryId) {
3830
- throw new Error('Memory id is required.');
3831
- }
3832
- return memoryId;
3833
- }
3834
- /**
3835
- * Collection of MEMORY tool argument parsers.
3836
- *
3837
- * @private function of MemoryCommitmentDefinition
3838
- */
3839
- const parseMemoryToolArgs = {
3840
- /**
3841
- * Parses retrieve memory arguments.
3842
- */
3843
- retrieve(args) {
3844
- const query = typeof args.query === 'string' ? args.query.trim() : undefined;
3845
- const limit = typeof args.limit === 'number' && Number.isFinite(args.limit) ? Math.floor(args.limit) : undefined;
3846
- return {
3847
- query: query && query.length > 0 ? query : undefined,
3848
- limit: limit && limit > 0 ? Math.min(limit, 20) : undefined,
3849
- };
3850
- },
3851
- /**
3852
- * Parses store memory arguments.
3853
- */
3854
- store(args) {
3855
- const content = typeof args.content === 'string' ? args.content.trim() : '';
3856
- if (!content) {
3857
- throw new Error('Memory content is required.');
3858
- }
3859
- return {
3860
- content,
3861
- isGlobal: args.isGlobal === true,
3862
- };
3863
- },
3864
- /**
3865
- * Parses update memory arguments.
3866
- */
3867
- update(args) {
3868
- const memoryId = parseMemoryIdArg(args.memoryId);
3869
- const content = typeof args.content === 'string' ? args.content.trim() : '';
3870
- if (!content) {
3871
- throw new Error('Memory content is required.');
3872
- }
3873
- const isGlobal = typeof args.isGlobal === 'boolean' ? args.isGlobal : undefined;
3874
- return {
3875
- memoryId,
3876
- content,
3877
- isGlobal,
3878
- };
3879
- },
3880
- /**
3881
- * Parses delete memory arguments.
3882
- */
3883
- delete(args) {
3884
- return {
3885
- memoryId: parseMemoryIdArg(args.memoryId),
3886
- };
3887
- },
3888
- };
3889
-
3890
- /**
3891
- * Prompt parameter key used to pass hidden runtime context to tool execution.
3892
- *
3893
- * @private internal runtime wiring for commitment tools
3894
- */
3895
- const TOOL_RUNTIME_CONTEXT_PARAMETER = 'promptbookToolRuntimeContext';
3896
- /**
3897
- * Hidden argument key used to pass runtime context into individual tool calls.
3898
- *
3899
- * @private internal runtime wiring for commitment tools
3900
- */
3901
- const TOOL_RUNTIME_CONTEXT_ARGUMENT = '__promptbookToolRuntimeContext';
3902
- /**
3903
- * Prompt parameter key used to pass a hidden tool-progress listener token into script execution.
3904
- *
3905
- * @private internal runtime wiring for commitment tools
3906
- */
3907
- const TOOL_PROGRESS_TOKEN_PARAMETER = 'promptbookToolProgressToken';
3908
- /**
3909
- * Hidden argument key used to pass a tool-progress listener token into individual tool calls.
3910
- *
3911
- * @private internal runtime wiring for commitment tools
3912
- */
3913
- const TOOL_PROGRESS_TOKEN_ARGUMENT = '__promptbookToolProgressToken';
3914
- /**
3915
- * Monotonic counter used for hidden progress-listener tokens.
3916
- *
3917
- * @private internal runtime wiring for commitment tools
3918
- */
3919
- let toolCallProgressListenerCounter = 0;
3920
- /**
3921
- * Active tool-progress listeners keyed by hidden execution token.
3922
- *
3923
- * @private internal runtime wiring for commitment tools
3924
- */
3925
- const toolCallProgressListeners = new Map();
3926
- /**
3927
- * Parses unknown runtime context payload into a normalized object.
3928
- *
3929
- * @private internal runtime wiring for commitment tools
3930
- */
3931
- function parseToolRuntimeContext(rawValue) {
3932
- if (!rawValue) {
3933
- return null;
3934
- }
3935
- let parsed = rawValue;
3936
- if (typeof rawValue === 'string') {
3937
- try {
3938
- parsed = JSON.parse(rawValue);
3939
- }
3940
- catch (_a) {
3941
- return null;
3942
- }
3943
- }
3944
- if (!parsed || typeof parsed !== 'object') {
3945
- return null;
3946
- }
3947
- return parsed;
3948
- }
3949
- /**
3950
- * Reads runtime context attached to tool call arguments.
3951
- *
3952
- * @private internal runtime wiring for commitment tools
3953
- */
3954
- function readToolRuntimeContextFromToolArgs(args) {
3955
- return parseToolRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]);
3956
- }
3957
- /**
3958
- * Serializes runtime context for prompt parameters.
3959
- *
3960
- * @private internal runtime wiring for commitment tools
3961
- */
3962
- function serializeToolRuntimeContext(context) {
3963
- return JSON.stringify(context);
3964
- }
3965
- /**
3966
- * Registers one in-memory listener that receives progress updates emitted by a running tool.
3967
- *
3968
- * The returned token is passed into script execution as a hidden argument so tool implementations
3969
- * can stream progress without exposing extra parameters to the model.
3970
- *
3971
- * @param listener - Listener notified about tool progress.
3972
- * @returns Hidden token used to route progress updates.
3973
- *
3974
- * @private internal runtime wiring for commitment tools
3975
- */
3976
- function registerToolCallProgressListener(listener) {
3977
- toolCallProgressListenerCounter += 1;
3978
- const token = `tool-progress:${Date.now()}:${toolCallProgressListenerCounter}`;
3979
- toolCallProgressListeners.set(token, listener);
3980
- return token;
3981
- }
3982
- /**
3983
- * Unregisters one in-memory progress listener.
3984
- *
3985
- * @param token - Token previously created by `registerToolCallProgressListener`.
3986
- *
3987
- * @private internal runtime wiring for commitment tools
3988
- */
3989
- function unregisterToolCallProgressListener(token) {
3990
- toolCallProgressListeners.delete(token);
3991
- }
3992
- // Note: [💞] Ignore a discrepancy between file name and entity name
3993
-
3994
- /**
3995
- * Resolves runtime context from hidden tool arguments.
3996
- *
3997
- * @private function of MemoryCommitmentDefinition
3998
- */
3999
- function resolveMemoryRuntimeContext(args) {
4000
- const runtimeContext = readToolRuntimeContextFromToolArgs(args);
4001
- const memoryContext = runtimeContext === null || runtimeContext === void 0 ? void 0 : runtimeContext.memory;
4002
- return {
4003
- enabled: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.enabled) === true,
4004
- userId: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.userId,
4005
- username: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.username,
4006
- agentId: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.agentId,
4007
- agentName: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.agentName,
4008
- isTeamConversation: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.isTeamConversation) === true,
4009
- isPrivateMode: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.isPrivateMode) === true,
4010
- };
4011
- }
4012
-
4013
- /**
4014
- * Gets MEMORY tool function implementations.
4015
- *
4016
- * @private function of MemoryCommitmentDefinition
4017
- */
4018
- function createMemoryToolFunctions() {
4019
- return {
4020
- async [MemoryToolNames.retrieve](args) {
4021
- const runtimeContext = resolveMemoryRuntimeContext(args);
4022
- const { adapter, disabledResult } = getMemoryToolRuntimeAdapterOrDisabledResult('retrieve', runtimeContext);
4023
- if (!adapter || disabledResult) {
4024
- return JSON.stringify(disabledResult);
4025
- }
4026
- const parsedArgs = parseMemoryToolArgs.retrieve(args);
4027
- try {
4028
- const memories = await adapter.retrieveMemories(parsedArgs, runtimeContext);
4029
- const result = {
4030
- action: 'retrieve',
4031
- status: 'ok',
4032
- query: parsedArgs.query,
4033
- memories,
4034
- };
4035
- return JSON.stringify(result);
4036
- }
4037
- catch (error) {
4038
- const result = {
4039
- action: 'retrieve',
4040
- status: 'error',
4041
- query: parsedArgs.query,
4042
- memories: [],
4043
- message: error instanceof Error ? error.message : String(error),
4044
- };
4045
- return JSON.stringify(result);
4046
- }
4047
- },
4048
- async [MemoryToolNames.store](args) {
4049
- const runtimeContext = resolveMemoryRuntimeContext(args);
4050
- const { adapter, disabledResult } = getMemoryToolRuntimeAdapterOrDisabledResult('store', runtimeContext);
4051
- if (!adapter || disabledResult) {
4052
- return JSON.stringify(disabledResult);
4053
- }
4054
- try {
4055
- const parsedArgs = parseMemoryToolArgs.store(args);
4056
- const memory = await adapter.storeMemory(parsedArgs, runtimeContext);
4057
- const result = {
4058
- action: 'store',
4059
- status: 'stored',
4060
- memory,
4061
- };
4062
- return JSON.stringify(result);
4063
- }
4064
- catch (error) {
4065
- const result = {
4066
- action: 'store',
4067
- status: 'error',
4068
- message: error instanceof Error ? error.message : String(error),
4069
- };
4070
- return JSON.stringify(result);
4071
- }
4072
- },
4073
- async [MemoryToolNames.update](args) {
4074
- const runtimeContext = resolveMemoryRuntimeContext(args);
4075
- const { adapter, disabledResult } = getMemoryToolRuntimeAdapterOrDisabledResult('update', runtimeContext);
4076
- if (!adapter || disabledResult) {
4077
- return JSON.stringify(disabledResult);
4078
- }
4079
- try {
4080
- const parsedArgs = parseMemoryToolArgs.update(args);
4081
- const memory = await adapter.updateMemory(parsedArgs, runtimeContext);
4082
- const result = {
4083
- action: 'update',
4084
- status: 'updated',
4085
- memory,
4086
- };
4087
- return JSON.stringify(result);
4088
- }
4089
- catch (error) {
4090
- const result = {
4091
- action: 'update',
4092
- status: 'error',
4093
- message: error instanceof Error ? error.message : String(error),
4094
- };
4095
- return JSON.stringify(result);
4096
- }
4097
- },
4098
- async [MemoryToolNames.delete](args) {
4099
- const runtimeContext = resolveMemoryRuntimeContext(args);
4100
- const { adapter, disabledResult } = getMemoryToolRuntimeAdapterOrDisabledResult('delete', runtimeContext);
4101
- if (!adapter || disabledResult) {
4102
- return JSON.stringify(disabledResult);
4103
- }
4104
- try {
4105
- const parsedArgs = parseMemoryToolArgs.delete(args);
4106
- const deleted = await adapter.deleteMemory(parsedArgs, runtimeContext);
4107
- const result = {
4108
- action: 'delete',
4109
- status: 'deleted',
4110
- memoryId: deleted.id,
4111
- };
4112
- return JSON.stringify(result);
4113
- }
4114
- catch (error) {
4115
- const result = {
4116
- action: 'delete',
4117
- status: 'error',
4118
- message: error instanceof Error ? error.message : String(error),
4119
- };
4120
- return JSON.stringify(result);
4121
- }
4122
- },
4123
- };
4124
- }
4125
-
4126
- /**
4127
- * Creates MEMORY tool definitions while preserving already-registered tools.
4128
- *
4129
- * @private function of MemoryCommitmentDefinition
4130
- */
4131
- function createMemoryTools(existingTools) {
4132
- const tools = [...(existingTools || [])];
4133
- if (!tools.some((tool) => tool.name === MemoryToolNames.retrieve)) {
4134
- tools.push({
4135
- name: MemoryToolNames.retrieve,
4136
- description: spacetrim.spaceTrim(`
4137
- Retrieve previously stored user memories relevant to the current conversation.
4138
- Use this before responding when user context can improve the answer.
4139
- `),
4140
- parameters: {
4141
- type: 'object',
4142
- properties: {
4143
- query: {
4144
- type: 'string',
4145
- description: 'Optional query used to filter relevant memories.',
4146
- },
4147
- limit: {
4148
- type: 'integer',
4149
- description: 'Optional maximum number of memories to return (default 5, max 20).',
4150
- },
4151
- },
4152
- },
4153
- });
4154
- }
4155
- if (!tools.some((tool) => tool.name === MemoryToolNames.store)) {
4156
- tools.push({
4157
- name: MemoryToolNames.store,
4158
- description: spacetrim.spaceTrim(`
4159
- Store a durable user memory that should be remembered in future conversations.
4160
- Store only stable and useful user-specific facts or preferences.
4161
- `),
4162
- parameters: {
4163
- type: 'object',
4164
- properties: {
4165
- content: {
4166
- type: 'string',
4167
- description: 'Memory text to store.',
4168
- },
4169
- isGlobal: {
4170
- type: 'boolean',
4171
- description: 'Set true to make this memory global across all user agents.',
4172
- },
4173
- },
4174
- required: ['content'],
4175
- },
4176
- });
4177
- }
4178
- if (!tools.some((tool) => tool.name === MemoryToolNames.update)) {
4179
- tools.push({
4180
- name: MemoryToolNames.update,
4181
- description: spacetrim.spaceTrim(`
4182
- Update an existing user memory after retrieving it, so the stored fact stays accurate.
4183
- Always pass the memory id you retrieved along with the new content.
4184
- `),
4185
- parameters: {
4186
- type: 'object',
4187
- properties: {
4188
- memoryId: {
4189
- type: 'string',
4190
- description: 'Unique identifier of the memory entry to update.',
4191
- },
4192
- content: {
4193
- type: 'string',
4194
- description: 'Updated memory text.',
4195
- },
4196
- isGlobal: {
4197
- type: 'boolean',
4198
- description: 'Set true to keep the fact global; omit or false to keep it agent-scoped.',
4199
- },
4200
- },
4201
- required: ['memoryId', 'content'],
4202
- },
4203
- });
4204
- }
4205
- if (!tools.some((tool) => tool.name === MemoryToolNames.delete)) {
4206
- tools.push({
4207
- name: MemoryToolNames.delete,
4208
- description: spacetrim.spaceTrim(`
4209
- Delete a user memory that is no longer relevant. Deletions are soft so the record is hidden from future queries.
4210
- `),
4211
- parameters: {
4212
- type: 'object',
4213
- properties: {
4214
- memoryId: {
4215
- type: 'string',
4216
- description: 'Unique identifier of the memory entry to delete.',
4217
- },
4218
- },
4219
- required: ['memoryId'],
4220
- },
4221
- });
4222
- }
4223
- return tools;
4224
- }
4225
-
4226
- /**
4227
- * Markdown documentation for MEMORY commitment.
4228
- *
4229
- * @private function of MemoryCommitmentDefinition
4230
- */
4231
- function getMemoryCommitmentDocumentation(type) {
4232
- return spacetrim.spaceTrim(`
4233
- # ${type}
4234
-
4235
- Enables persistent user memory for the current agent. The memory is stored by the runtime and can be retrieved in future conversations.
4236
-
4237
- ## Key aspects
4238
-
4239
- - Both \`MEMORY\` and \`MEMORIES\` work identically.
4240
- - Stores user-specific details through runtime tools.
4241
- - Retrieves relevant memories for personalized responses.
4242
- - Supports optional extra instructions in the commitment content.
4243
-
4244
- ## Examples
4245
-
4246
- \`\`\`book
4247
- Personal Assistant
4248
-
4249
- PERSONA You are a personal productivity assistant
4250
- MEMORY Remember user projects and long-term preferences.
4251
- GOAL Help optimize daily productivity and workflow
4252
- \`\`\`
4253
-
4254
- \`\`\`book
4255
- Learning Companion
4256
-
4257
- PERSONA You are an educational companion for programming students
4258
- MEMORY Remember only the student's learning progress and preferred study style.
4259
- GOAL Provide progressive learning experiences tailored to student's pace
4260
- \`\`\`
4261
-
4262
- \`\`\`book
4263
- Customer Support Agent
4264
-
4265
- PERSONA You are a customer support representative
4266
- MEMORY Remember only important support history and communication preferences.
4267
- GOAL Provide personalized support based on customer history
4268
- \`\`\`
4269
- `);
4270
- }
4271
-
4272
- /**
4273
- * Gets human-readable titles for MEMORY tool functions.
4274
- *
4275
- * @private function of MemoryCommitmentDefinition
4276
- */
4277
- function getMemoryToolTitles() {
4278
- return {
4279
- [MemoryToolNames.retrieve]: 'User memory',
4280
- [MemoryToolNames.store]: 'Store user memory',
4281
- [MemoryToolNames.update]: 'Update user memory',
4282
- [MemoryToolNames.delete]: 'Delete user memory',
4283
- };
4284
- }
4285
-
4286
- /**
4287
- * MEMORY commitment definition
4288
- *
4289
- * The MEMORY commitment is similar to KNOWLEDGE but has a focus on remembering past
4290
- * interactions and user preferences. It helps the agent maintain context about the
4291
- * user's history, preferences, and previous conversations.
4292
- *
4293
- * Example usage in agent source:
4294
- *
4295
- * ```book
4296
- * MEMORY User prefers detailed technical explanations
4297
- * MEMORY Previously worked on React projects
4298
- * MEMORY Timezone: UTC-5 (Eastern Time)
4299
- * ```
4300
- *
4301
- * @private [🪔] Maybe export the commitments through some package
4302
- */
4303
- class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
4304
- constructor(type = 'MEMORY') {
4305
- super(type);
4306
- }
4307
- get requiresContent() {
4308
- return false;
4309
- }
4310
- /**
4311
- * Short one-line description of MEMORY.
4312
- */
4313
- get description() {
4314
- return 'Remember past interactions and user **preferences** for personalized responses.';
4315
- }
4316
- /**
4317
- * Icon for this commitment.
4318
- */
4319
- get icon() {
4320
- return '🧠';
4321
- }
4322
- /**
4323
- * Markdown documentation for MEMORY commitment.
4324
- */
4325
- get documentation() {
4326
- return getMemoryCommitmentDocumentation(this.type);
4327
- }
4328
- applyToAgentModelRequirements(requirements, content) {
4329
- const extraInstructions = formatOptionalInstructionBlock('Memory instructions', content);
4330
- const tools = createMemoryTools(requirements.tools);
4331
- return this.appendToSystemMessage({
4332
- ...requirements,
4333
- tools,
4334
- _metadata: {
4335
- ...requirements._metadata,
4336
- useMemory: content || true,
4337
- },
4338
- }, createMemorySystemMessage(extraInstructions));
4339
- }
4340
- /**
4341
- * Gets human-readable titles for MEMORY tool functions.
4342
- */
4343
- getToolTitles() {
4344
- return getMemoryToolTitles();
4345
- }
4346
- /**
4347
- * Gets MEMORY tool function implementations.
4348
- */
4349
- getToolFunctions() {
4350
- return createMemoryToolFunctions();
4351
- }
4352
- }
4353
- // Note: [💞] Ignore a discrepancy between file name and entity name
4354
-
4355
3648
  /**
4356
3649
  * AGENT MESSAGE commitment definition
4357
3650
  *
@@ -4811,161 +4104,6 @@
4811
4104
  }
4812
4105
  // Note: [💞] Ignore a discrepancy between file name and entity name
4813
4106
 
4814
- /**
4815
- * META commitment definition
4816
- *
4817
- * The META commitment handles all meta-information about the agent such as:
4818
- * - META AVATAR / META VISUAL: Sets the agent's built-in default avatar visual
4819
- * - META IMAGE: Sets the agent's avatar/profile image URL
4820
- * - META LINK: Provides profile/source links for the person the agent models
4821
- * - META DOMAIN: Sets the canonical custom domain/host of the agent
4822
- * - META TITLE: Sets the agent's display title
4823
- * - META DESCRIPTION: Sets the agent's description
4824
- * - META INPUT PLACEHOLDER: Sets chat input placeholder text
4825
- * - META THINKING MESSAGE: Adds custom thinking placeholder variants
4826
- * - META [ANYTHING]: Any other meta information in uppercase format
4827
- *
4828
- * These commitments are special because they don't affect the system message,
4829
- * but are handled separately in the parsing logic for profile display.
4830
- *
4831
- * Example usage in agent source:
4832
- *
4833
- * ```book
4834
- * META VISUAL pixel-art
4835
- * META IMAGE https://example.com/avatar.jpg
4836
- * META LINK https://twitter.com/username
4837
- * META DOMAIN my-agent.com
4838
- * META TITLE Professional Assistant
4839
- * META DESCRIPTION An AI assistant specialized in business tasks
4840
- * META INPUT PLACEHOLDER Write a message...
4841
- * META THINKING MESSAGE Thinking...
4842
- * META AUTHOR John Doe
4843
- * META VERSION 1.0
4844
- * ```
4845
- *
4846
- * @private [🪔] Maybe export the commitments through some package
4847
- */
4848
- class MetaCommitmentDefinition extends BaseCommitmentDefinition {
4849
- constructor() {
4850
- super('META');
4851
- }
4852
- /**
4853
- * Short one-line description of META commitments.
4854
- */
4855
- get description() {
4856
- return 'Set meta-information about the agent (IMAGE, LINK, TITLE, DESCRIPTION, etc.).';
4857
- }
4858
- /**
4859
- * Icon for this commitment.
4860
- */
4861
- get icon() {
4862
- return 'ℹ️';
4863
- }
4864
- /**
4865
- * Markdown documentation for META commitment.
4866
- */
4867
- get documentation() {
4868
- return spacetrim.spaceTrim(`
4869
- # META
4870
-
4871
- Sets meta-information about the agent that is used for display and attribution purposes.
4872
-
4873
- ## Supported META types
4874
-
4875
- - **META AVATAR** / **META VISUAL** - Sets the agent's built-in default avatar visual
4876
- - **META IMAGE** - Sets the agent's avatar/profile image URL
4877
- - **META LINK** - Provides profile/source links for the person the agent models
4878
- - **META DOMAIN** - Sets the canonical custom domain/host of the agent
4879
- - **META TITLE** - Sets the agent's display title
4880
- - **META DESCRIPTION** - Sets the agent's description
4881
- - **META INPUT PLACEHOLDER** - Sets chat input placeholder text
4882
- - **META THINKING MESSAGE** - Adds custom thinking placeholder variants
4883
- - **META [ANYTHING]** - Any other meta information in uppercase format
4884
-
4885
- ## Key aspects
4886
-
4887
- - Does not modify the agent's behavior or responses
4888
- - Used for visual representation and attribution in user interfaces
4889
- - Multiple META commitments of different types can be used
4890
- - Multiple META LINK commitments can be used for different social profiles
4891
- - Multiple META THINKING MESSAGE commitments can be used for different thinking placeholder variants
4892
- - If multiple META commitments of the same type are specified, the last one takes precedence (except for LINK)
4893
-
4894
- ## Examples
4895
-
4896
- ### Basic meta information
4897
-
4898
- \`\`\`book
4899
- Professional Assistant
4900
-
4901
- META VISUAL octopus3
4902
- META IMAGE https://example.com/professional-avatar.jpg
4903
- META TITLE Senior Business Consultant
4904
- META DESCRIPTION Specialized in strategic planning and project management
4905
- META LINK https://linkedin.com/in/professional
4906
- \`\`\`
4907
-
4908
- ### Multiple links and custom meta
4909
-
4910
- \`\`\`book
4911
- Open Source Developer
4912
-
4913
- META IMAGE /assets/dev-avatar.png
4914
- META LINK https://github.com/developer
4915
- META LINK https://twitter.com/devhandle
4916
- META AUTHOR Jane Smith
4917
- META VERSION 2.1
4918
- META LICENSE MIT
4919
- \`\`\`
4920
-
4921
- ### Creative assistant
4922
-
4923
- \`\`\`book
4924
- Creative Helper
4925
-
4926
- META IMAGE https://example.com/creative-bot.jpg
4927
- META TITLE Creative Writing Assistant
4928
- META DESCRIPTION Helps with brainstorming, storytelling, and creative projects
4929
- META INSPIRATION Books, movies, and real-world experiences
4930
- \`\`\`
4931
- `);
4932
- }
4933
- applyToAgentModelRequirements(requirements, content) {
4934
- // META commitments don't modify the system message or model requirements
4935
- // They are handled separately in the parsing logic for meta information extraction
4936
- // This method exists for consistency with the CommitmentDefinition interface
4937
- return requirements;
4938
- }
4939
- /**
4940
- * Extracts meta information from the content based on the meta type
4941
- * This is used by the parsing logic
4942
- */
4943
- extractMetaValue(metaType, content) {
4944
- const trimmedContent = content.trim();
4945
- return trimmedContent || null;
4946
- }
4947
- /**
4948
- * Validates if the provided content is a valid URL (for IMAGE and LINK types)
4949
- */
4950
- isValidUrl(content) {
4951
- try {
4952
- new URL(content.trim());
4953
- return true;
4954
- }
4955
- catch (_a) {
4956
- return false;
4957
- }
4958
- }
4959
- /**
4960
- * Checks if this is a known meta type
4961
- */
4962
- isKnownMetaType(metaType) {
4963
- const knownTypes = ['AVATAR', 'IMAGE', 'LINK', 'TITLE', 'DESCRIPTION', 'AUTHOR', 'VERSION', 'LICENSE'];
4964
- return knownTypes.includes(metaType.toUpperCase());
4965
- }
4966
- }
4967
- // Note: [💞] Ignore a discrepancy between file name and entity name
4968
-
4969
4107
  /**
4970
4108
  * Makes color transformer which darker the given color
4971
4109
  *
@@ -11216,6 +10354,81 @@
11216
10354
  }
11217
10355
  // Note: [💞] Ignore a discrepancy between file name and entity name
11218
10356
 
10357
+ /**
10358
+ * META DESCRIPTION commitment definition
10359
+ *
10360
+ * The META DESCRIPTION commitment sets the agent's meta description for the profile page.
10361
+ * This commitment is special because it doesn't affect the system message,
10362
+ * but is handled separately in the parsing logic.
10363
+ *
10364
+ * Example usage in agent source:
10365
+ *
10366
+ * ```book
10367
+ * META DESCRIPTION An AI assistant specialized in business tasks
10368
+ * ```
10369
+ *
10370
+ * @private [🪔] Maybe export the commitments through some package
10371
+ */
10372
+ class MetaDescriptionCommitmentDefinition extends BaseCommitmentDefinition {
10373
+ constructor() {
10374
+ super('META DESCRIPTION');
10375
+ }
10376
+ /**
10377
+ * Short one-line description of META DESCRIPTION.
10378
+ */
10379
+ get description() {
10380
+ return "Set the agent's meta description.";
10381
+ }
10382
+ /**
10383
+ * Icon for this commitment.
10384
+ */
10385
+ get icon() {
10386
+ return '📝';
10387
+ }
10388
+ /**
10389
+ * Markdown documentation for META DESCRIPTION commitment.
10390
+ */
10391
+ get documentation() {
10392
+ return spacetrim.spaceTrim(`
10393
+ # META DESCRIPTION
10394
+
10395
+ Sets the agent's meta description for the profile page.
10396
+
10397
+ ## Key aspects
10398
+
10399
+ - Does not modify the agent's behavior or responses.
10400
+ - Only one \`META DESCRIPTION\` should be used per agent.
10401
+ - If multiple are specified, the last one takes precedence.
10402
+ - Used for SEO and display in user interfaces.
10403
+ - If not present, the agent description falls back to \`PERSONA\` or the first few lines of the agent source.
10404
+
10405
+ ## Examples
10406
+
10407
+ \`\`\`book
10408
+ Professional Assistant
10409
+
10410
+ META DESCRIPTION Specialized in strategic planning and project management
10411
+ PERSONA You are a professional business assistant
10412
+ WRITING RULES Maintain a formal and courteous tone
10413
+ \`\`\`
10414
+ `);
10415
+ }
10416
+ applyToAgentModelRequirements(requirements, content) {
10417
+ // META DESCRIPTION doesn't modify the system message or model requirements
10418
+ // It's handled separately in the parsing logic
10419
+ return requirements;
10420
+ }
10421
+ /**
10422
+ * Extracts the meta description from the content
10423
+ * This is used by the parsing logic
10424
+ */
10425
+ extractMetaDescription(content) {
10426
+ const trimmedContent = content.trim();
10427
+ return trimmedContent || null;
10428
+ }
10429
+ }
10430
+ // Note: [💞] Ignore a discrepancy between file name and entity name
10431
+
11219
10432
  /**
11220
10433
  * META DOMAIN commitment definition
11221
10434
  *
@@ -11432,6 +10645,131 @@
11432
10645
  }
11433
10646
  // Note: [💞] Ignore a discrepancy between file name and entity name
11434
10647
 
10648
+ /**
10649
+ * META FULLNAME commitment definition
10650
+ *
10651
+ * The `META FULLNAME` commitment sets the full display name of the agent, which can differ
10652
+ * from the agent name on the first line of the agent source, for example when the agent
10653
+ * should be presented with academic titles.
10654
+ * This commitment is metadata-only and does not modify model requirements.
10655
+ *
10656
+ * @private [🪔] Maybe export the commitments through some package
10657
+ */
10658
+ class MetaFullnameCommitmentDefinition extends BaseCommitmentDefinition {
10659
+ constructor() {
10660
+ super('META FULLNAME');
10661
+ }
10662
+ /**
10663
+ * Short one-line description of META FULLNAME.
10664
+ */
10665
+ get description() {
10666
+ return "Set the agent's full display name.";
10667
+ }
10668
+ /**
10669
+ * Icon for this commitment.
10670
+ */
10671
+ get icon() {
10672
+ return '🪪';
10673
+ }
10674
+ /**
10675
+ * Markdown documentation for META FULLNAME commitment.
10676
+ */
10677
+ get documentation() {
10678
+ return spacetrim.spaceTrim(`
10679
+ # META FULLNAME
10680
+
10681
+ Sets the full display name of the agent shown in profiles, chats, and exports.
10682
+
10683
+ ## Key aspects
10684
+
10685
+ - Does not modify the agent's behavior or responses.
10686
+ - If not present, the agent name from the first line of the agent source is used.
10687
+ - If multiple \`META FULLNAME\` commitments are specified, the last one takes precedence.
10688
+
10689
+ ## Examples
10690
+
10691
+ \`\`\`book
10692
+ Pavol Hejný
10693
+
10694
+ META FULLNAME Dr. Ing. Pavol Hejný, PhD.
10695
+ PERSONA Developer with 10 years of experience in building AI applications.
10696
+ \`\`\`
10697
+ `);
10698
+ }
10699
+ applyToAgentModelRequirements(requirements, content) {
10700
+ // META FULLNAME does not modify the model requirements.
10701
+ // It is consumed by profile parsing.
10702
+ return requirements;
10703
+ }
10704
+ }
10705
+ // Note: [💞] Ignore a discrepancy between file name and entity name
10706
+
10707
+ /**
10708
+ * META ID commitment definition
10709
+ *
10710
+ * The `META ID` commitment carries the permanent id of the agent when an agent source is moved
10711
+ * between systems. It is a low-level commitment which is normally written and stripped by the
10712
+ * persistence layer instead of being written by hand.
10713
+ * This commitment is metadata-only and does not modify model requirements.
10714
+ *
10715
+ * @private [🪔] Maybe export the commitments through some package
10716
+ */
10717
+ class MetaIdCommitmentDefinition extends BaseCommitmentDefinition {
10718
+ constructor() {
10719
+ super('META ID');
10720
+ }
10721
+ /**
10722
+ * Short one-line description of META ID.
10723
+ */
10724
+ get description() {
10725
+ return "Set the agent's permanent id.";
10726
+ }
10727
+ /**
10728
+ * Icon for this commitment.
10729
+ */
10730
+ get icon() {
10731
+ return '🔖';
10732
+ }
10733
+ /**
10734
+ * `META ID` is written by the persistence layer, not by agent authors.
10735
+ */
10736
+ get isLowLevel() {
10737
+ return true;
10738
+ }
10739
+ /**
10740
+ * Markdown documentation for META ID commitment.
10741
+ */
10742
+ get documentation() {
10743
+ return spacetrim.spaceTrim(`
10744
+ # META ID
10745
+
10746
+ Carries the permanent id of the agent inside the agent source.
10747
+
10748
+ ## Key aspects
10749
+
10750
+ - Does not modify the agent's behavior or responses.
10751
+ - Written and stripped by the persistence layer, it should not be written by hand.
10752
+ - When an agent source without \`META ID\` is stored, a fresh permanent id is assigned.
10753
+ - If multiple \`META ID\` commitments are specified, the last one takes precedence.
10754
+
10755
+ ## Examples
10756
+
10757
+ \`\`\`book
10758
+ My agent
10759
+
10760
+ META ID doQMRg82izNfJa
10761
+ PERSONA My agent is an expert in something.
10762
+ \`\`\`
10763
+ `);
10764
+ }
10765
+ applyToAgentModelRequirements(requirements, content) {
10766
+ // META ID does not modify the model requirements.
10767
+ // It is consumed by profile parsing and agent persistence.
10768
+ return requirements;
10769
+ }
10770
+ }
10771
+ // Note: [💞] Ignore a discrepancy between file name and entity name
10772
+
11435
10773
  /**
11436
10774
  * META IMAGE commitment definition
11437
10775
  *
@@ -13215,6 +12553,110 @@
13215
12553
  }
13216
12554
  // Note: [💞] Ignore a discrepancy between file name and entity name
13217
12555
 
12556
+ /**
12557
+ * Prompt parameter key used to pass hidden runtime context to tool execution.
12558
+ *
12559
+ * @private internal runtime wiring for commitment tools
12560
+ */
12561
+ const TOOL_RUNTIME_CONTEXT_PARAMETER = 'promptbookToolRuntimeContext';
12562
+ /**
12563
+ * Hidden argument key used to pass runtime context into individual tool calls.
12564
+ *
12565
+ * @private internal runtime wiring for commitment tools
12566
+ */
12567
+ const TOOL_RUNTIME_CONTEXT_ARGUMENT = '__promptbookToolRuntimeContext';
12568
+ /**
12569
+ * Prompt parameter key used to pass a hidden tool-progress listener token into script execution.
12570
+ *
12571
+ * @private internal runtime wiring for commitment tools
12572
+ */
12573
+ const TOOL_PROGRESS_TOKEN_PARAMETER = 'promptbookToolProgressToken';
12574
+ /**
12575
+ * Hidden argument key used to pass a tool-progress listener token into individual tool calls.
12576
+ *
12577
+ * @private internal runtime wiring for commitment tools
12578
+ */
12579
+ const TOOL_PROGRESS_TOKEN_ARGUMENT = '__promptbookToolProgressToken';
12580
+ /**
12581
+ * Monotonic counter used for hidden progress-listener tokens.
12582
+ *
12583
+ * @private internal runtime wiring for commitment tools
12584
+ */
12585
+ let toolCallProgressListenerCounter = 0;
12586
+ /**
12587
+ * Active tool-progress listeners keyed by hidden execution token.
12588
+ *
12589
+ * @private internal runtime wiring for commitment tools
12590
+ */
12591
+ const toolCallProgressListeners = new Map();
12592
+ /**
12593
+ * Parses unknown runtime context payload into a normalized object.
12594
+ *
12595
+ * @private internal runtime wiring for commitment tools
12596
+ */
12597
+ function parseToolRuntimeContext(rawValue) {
12598
+ if (!rawValue) {
12599
+ return null;
12600
+ }
12601
+ let parsed = rawValue;
12602
+ if (typeof rawValue === 'string') {
12603
+ try {
12604
+ parsed = JSON.parse(rawValue);
12605
+ }
12606
+ catch (_a) {
12607
+ return null;
12608
+ }
12609
+ }
12610
+ if (!parsed || typeof parsed !== 'object') {
12611
+ return null;
12612
+ }
12613
+ return parsed;
12614
+ }
12615
+ /**
12616
+ * Reads runtime context attached to tool call arguments.
12617
+ *
12618
+ * @private internal runtime wiring for commitment tools
12619
+ */
12620
+ function readToolRuntimeContextFromToolArgs(args) {
12621
+ return parseToolRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]);
12622
+ }
12623
+ /**
12624
+ * Serializes runtime context for prompt parameters.
12625
+ *
12626
+ * @private internal runtime wiring for commitment tools
12627
+ */
12628
+ function serializeToolRuntimeContext(context) {
12629
+ return JSON.stringify(context);
12630
+ }
12631
+ /**
12632
+ * Registers one in-memory listener that receives progress updates emitted by a running tool.
12633
+ *
12634
+ * The returned token is passed into script execution as a hidden argument so tool implementations
12635
+ * can stream progress without exposing extra parameters to the model.
12636
+ *
12637
+ * @param listener - Listener notified about tool progress.
12638
+ * @returns Hidden token used to route progress updates.
12639
+ *
12640
+ * @private internal runtime wiring for commitment tools
12641
+ */
12642
+ function registerToolCallProgressListener(listener) {
12643
+ toolCallProgressListenerCounter += 1;
12644
+ const token = `tool-progress:${Date.now()}:${toolCallProgressListenerCounter}`;
12645
+ toolCallProgressListeners.set(token, listener);
12646
+ return token;
12647
+ }
12648
+ /**
12649
+ * Unregisters one in-memory progress listener.
12650
+ *
12651
+ * @param token - Token previously created by `registerToolCallProgressListener`.
12652
+ *
12653
+ * @private internal runtime wiring for commitment tools
12654
+ */
12655
+ function unregisterToolCallProgressListener(token) {
12656
+ toolCallProgressListeners.delete(token);
12657
+ }
12658
+ // Note: [💞] Ignore a discrepancy between file name and entity name
12659
+
13218
12660
  /**
13219
12661
  * Map of team tool functions.
13220
12662
  */
@@ -13802,430 +13244,23 @@
13802
13244
  // Note: [💞] Ignore a discrepancy between file name and entity name
13803
13245
 
13804
13246
  /**
13805
- * All `USE` commitment types currently participating in final system-message aggregation.
13806
- *
13807
- * @private internal constant for `aggregateUseCommitmentSystemMessages`
13808
- */
13809
- const AGGREGATED_USE_COMMITMENT_TYPES = [
13810
- 'USE BROWSER',
13811
- 'USE DEEPSEARCH',
13812
- 'USE SEARCH ENGINE',
13813
- 'USE TIME',
13814
- ];
13815
- /**
13816
- * Prefix used for temporary in-system-message placeholders that preserve the first-occurrence position of aggregated `USE` sections.
13817
- *
13818
- * @private internal constant for `appendAggregatedUseCommitmentPlaceholder`
13819
- */
13820
- const AGGREGATED_USE_COMMITMENT_PLACEHOLDER_PREFIX = '# AGGREGATED USE COMMITMENT: ';
13821
- /**
13822
- * Type guard for `USE` commitment types that are aggregated in the final system message.
13823
- *
13824
- * @param type - Commitment type to check.
13825
- * @returns `true` when the commitment participates in `USE` system-message aggregation.
13826
- *
13827
- * @private internal utility of `aggregateUseCommitmentSystemMessages`
13828
- */
13829
- function isAggregatedUseCommitmentType(type) {
13830
- return AGGREGATED_USE_COMMITMENT_TYPES.includes(type);
13831
- }
13832
- /**
13833
- * Creates the placeholder token used to reserve the first-occurrence position of an aggregated `USE` system-message section.
13834
- *
13835
- * @param type - Aggregated `USE` commitment type.
13836
- * @returns Single-line placeholder comment stored in the interim system message.
13837
- *
13838
- * @private internal utility of `appendAggregatedUseCommitmentPlaceholder`
13839
- */
13840
- function getAggregatedUseCommitmentPlaceholder(type) {
13841
- return `${AGGREGATED_USE_COMMITMENT_PLACEHOLDER_PREFIX}${type}`;
13842
- }
13843
- /**
13844
- * Combines distinct additional instruction blocks in source order.
13845
- *
13846
- * @param additionalInstructions - Deduplicated instruction blocks collected from the agent source.
13847
- * @returns Combined instruction text ready for `formatOptionalInstructionBlock`.
13848
- *
13849
- * @private internal utility of `createAggregatedUseCommitmentSystemMessage`
13850
- */
13851
- function combineAdditionalInstructions(additionalInstructions) {
13852
- return additionalInstructions.join('\n');
13853
- }
13854
- /**
13855
- * Creates the final aggregated system-message section for a supported `USE` commitment type.
13856
- *
13857
- * @param type - Aggregated `USE` commitment type.
13858
- * @param additionalInstructions - Distinct additional instructions in source order.
13859
- * @returns Final system-message block for the commitment type.
13860
- *
13861
- * @private internal utility of `aggregateUseCommitmentSystemMessages`
13862
- */
13863
- function createAggregatedUseCommitmentSystemMessage(type, additionalInstructions) {
13864
- const combinedAdditionalInstructions = combineAdditionalInstructions(additionalInstructions);
13865
- switch (type) {
13866
- case 'USE TIME':
13867
- return spacetrim.spaceTrim((block) => `
13868
- ## Time and date context
13869
-
13870
- - It is ${moment__default["default"]().format('MMMM YYYY')} now.
13871
- - If you need more precise current time information, use the tool \`get_current_time\`.
13872
- ${block(formatOptionalInstructionBlock('Time instructions', combinedAdditionalInstructions))}
13873
- `);
13874
- case 'USE BROWSER':
13875
- return spacetrim.spaceTrim((block) => `
13876
- ## Browser
13877
-
13878
- - Use \`fetch_url_content\` to retrieve content from specific URLs (webpages or documents) using scrapers.
13879
- - Use \`run_browser\` for real interactive browser automation (navigation, clicks, typing, waiting, scrolling).
13880
- - When you need to know information from a specific website or document, use the tools provided.
13881
- ${block(formatOptionalInstructionBlock('Browser instructions', combinedAdditionalInstructions))}
13882
- `);
13883
- case 'USE SEARCH ENGINE':
13884
- return spacetrim.spaceTrim((block) => `
13885
- ## Web Search
13886
-
13887
- - Use \`web_search\` to find up-to-date information or facts.
13888
- - When you need to know some information from the internet, use the search tool provided.
13889
- - Do not make up information when you can search for it.
13890
- - Do not tell the user you cannot search for information, YOU CAN.
13891
- ${block(formatOptionalInstructionBlock('Search instructions', combinedAdditionalInstructions))}
13892
- `);
13893
- case 'USE DEEPSEARCH':
13894
- return spacetrim.spaceTrim((block) => `
13895
- ## Deep Research
13896
-
13897
- - Use \`deep_search\` for broader research tasks that need multi-step investigation, comparison, or synthesis across multiple sources.
13898
- - Prefer it over quick search when the user asks for a well-grounded brief, report, or deeper investigation.
13899
- - Do not pretend you cannot research current information when this tool is available.
13900
- ${block(formatOptionalInstructionBlock('DeepSearch instructions', combinedAdditionalInstructions))}
13901
- `);
13902
- }
13903
- }
13904
- /**
13905
- * Adds the placeholder for an aggregated `USE` system-message section only once, preserving the section position from the first occurrence.
13906
- *
13907
- * @param requirements - Current model requirements.
13908
- * @param type - Aggregated `USE` commitment type being applied.
13909
- * @returns Requirements with the placeholder inserted when it was not already present.
13910
- *
13911
- * @private internal utility of `USE` commitments
13912
- */
13913
- function appendAggregatedUseCommitmentPlaceholder(requirements, type) {
13914
- const placeholder = getAggregatedUseCommitmentPlaceholder(type);
13915
- if (requirements.systemMessage.includes(placeholder)) {
13916
- return requirements;
13917
- }
13918
- const systemMessage = requirements.systemMessage.trim()
13919
- ? `${requirements.systemMessage}\n\n${placeholder}`
13920
- : placeholder;
13921
- return {
13922
- ...requirements,
13923
- systemMessage,
13924
- };
13925
- }
13926
- /**
13927
- * Replaces temporary `USE` placeholders with one aggregated system-message block per commitment type.
13928
- *
13929
- * Distinct additional-instruction blocks are merged in stable source order while the hard-coded section is emitted only once.
13930
- *
13931
- * @param requirements - Model requirements produced by commitment-by-commitment application.
13932
- * @param commitments - Filtered commitments in their original source order.
13933
- * @returns Requirements with aggregated `USE` system-message sections.
13934
- *
13935
- * @private internal utility of `createAgentModelRequirementsWithCommitments`
13936
- */
13937
- function aggregateUseCommitmentSystemMessages(requirements, commitments) {
13938
- const additionalInstructionsByType = new Map();
13939
- for (const commitment of commitments) {
13940
- if (!isAggregatedUseCommitmentType(commitment.type)) {
13941
- continue;
13942
- }
13943
- let additionalInstructions = additionalInstructionsByType.get(commitment.type);
13944
- if (!additionalInstructions) {
13945
- additionalInstructions = [];
13946
- additionalInstructionsByType.set(commitment.type, additionalInstructions);
13947
- }
13948
- const normalizedContent = spacetrim.spaceTrim(commitment.content);
13949
- if (normalizedContent && !additionalInstructions.includes(normalizedContent)) {
13950
- additionalInstructions.push(normalizedContent);
13951
- }
13952
- }
13953
- let systemMessage = requirements.systemMessage;
13954
- for (const [type, additionalInstructions] of additionalInstructionsByType) {
13955
- const placeholder = getAggregatedUseCommitmentPlaceholder(type);
13956
- if (!systemMessage.includes(placeholder)) {
13957
- continue;
13958
- }
13959
- systemMessage = systemMessage.replace(placeholder, createAggregatedUseCommitmentSystemMessage(type, additionalInstructions));
13960
- }
13961
- return {
13962
- ...requirements,
13963
- systemMessage,
13964
- };
13965
- }
13966
-
13967
- /**
13968
- * Client-side safe wrapper for fetching URL content
13969
- *
13970
- * This function proxies requests to the Agents Server API endpoint for scraping,
13971
- * making it safe to use in browser environments.
13972
- *
13973
- * @param url The URL to fetch and scrape
13974
- * @param agentsServerUrl The base URL of the agents server (defaults to current origin)
13975
- * @returns Markdown content from the URL
13976
- *
13977
- * @private internal utility for USE BROWSER commitment
13978
- */
13979
- async function fetchUrlContentViaBrowser(url, agentsServerUrl) {
13980
- try {
13981
- // Determine the agents server URL
13982
- const baseUrl = agentsServerUrl || (typeof window !== 'undefined' ? window.location.origin : '');
13983
- if (!baseUrl) {
13984
- throw new Error('Agents server URL is required in non-browser environments');
13985
- }
13986
- // Build the API endpoint URL
13987
- const apiUrl = new URL('/api/scrape', baseUrl);
13988
- apiUrl.searchParams.set('url', url);
13989
- // Fetch from the API endpoint
13990
- const response = await fetch(apiUrl.toString());
13991
- if (!response.ok) {
13992
- const errorData = await response.json().catch(() => ({ error: 'Unknown error' }));
13993
- throw new Error(`Failed to scrape URL: ${errorData.error || response.statusText}`);
13994
- }
13995
- const data = await response.json();
13996
- if (!data.success || !data.content) {
13997
- throw new Error(`Scraping failed: ${data.error || 'No content returned'}`);
13998
- }
13999
- return data.content;
14000
- }
14001
- catch (error) {
14002
- const errorMessage = error instanceof Error ? error.message : String(error);
14003
- throw new Error(`Error fetching URL content via browser: ${errorMessage}`);
14004
- }
14005
- }
14006
-
14007
- /**
14008
- * USE BROWSER commitment definition
14009
- *
14010
- * The `USE BROWSER` commitment indicates that the agent should utilize browser tools
14011
- * to access and retrieve up-to-date information from the internet when necessary.
14012
- *
14013
- * This commitment provides two levels of browser access:
14014
- * 1. One-shot URL fetching: Simple function to fetch and scrape URL content
14015
- * 2. Running browser: For complex tasks like scrolling, clicking, form filling, etc.
14016
- *
14017
- * The content following `USE BROWSER` is an arbitrary text that the agent should know
14018
- * (e.g. browsing scope or preferred sources).
14019
- *
14020
- * Example usage in agent source:
14021
- *
14022
- * ```book
14023
- * USE BROWSER
14024
- * USE BROWSER Prefer official documentation and source websites.
14025
- * ```
13247
+ * @@@
14026
13248
  *
14027
- * @private [🪔] Maybe export the commitments through some package
13249
+ * @private utility for commitments
14028
13250
  */
14029
- class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
14030
- constructor() {
14031
- super('USE BROWSER', ['BROWSER']);
14032
- }
14033
- /**
14034
- * The `USE BROWSER` commitment is standalone.
14035
- */
14036
- get requiresContent() {
14037
- return false;
14038
- }
14039
- /**
14040
- * Short one-line description of USE BROWSER.
14041
- */
14042
- get description() {
14043
- return 'Enable the agent to use browser tools for accessing internet information.';
14044
- }
14045
- /**
14046
- * Icon for this commitment.
14047
- */
14048
- get icon() {
14049
- return '🌐';
14050
- }
14051
- /**
14052
- * Markdown documentation for USE BROWSER commitment.
14053
- */
14054
- get documentation() {
14055
- return spacetrim.spaceTrim(`
14056
- # USE BROWSER
14057
-
14058
- Enables the agent to use browser tools to access and retrieve up-to-date information from the internet.
14059
-
14060
- ## Key aspects
14061
-
14062
- - The content following \`USE BROWSER\` is an arbitrary text that the agent should know (e.g. browsing scope or preferred sources).
14063
- - Provides two levels of browser access:
14064
- 1. **One-shot URL fetching**: Simple function to fetch and scrape URL content (active)
14065
- 2. **Running browser**: For complex tasks like scrolling, clicking, form filling, etc. (runtime-dependent)
14066
- - The actual browser tool usage is handled by the agent runtime
14067
- - On the Agents Server, every agent browses in its own persistent isolated browser profile, so cookies and logged-in sessions survive across chats (the profile is linked from the agent wallet)
14068
- - Allows the agent to fetch current information from websites and documents
14069
- - Useful for research tasks, fact-checking, and accessing dynamic content
14070
- - Supports various content types including HTML pages and PDF documents
14071
-
14072
- ## Examples
14073
-
14074
- \`\`\`book
14075
- Research Assistant
14076
-
14077
- PERSONA You are a helpful research assistant specialized in finding current information
14078
- USE BROWSER
14079
- RULE Always cite your sources when providing information from the web
14080
- \`\`\`
14081
-
14082
- \`\`\`book
14083
- News Analyst
14084
-
14085
- PERSONA You are a news analyst who stays up-to-date with current events
14086
- USE BROWSER
14087
- WRITING RULES Present news in a balanced and objective manner
14088
- ACTION Can search for and summarize news articles
14089
- \`\`\`
14090
-
14091
- \`\`\`book
14092
- Company Lawyer
14093
-
14094
- PERSONA You are a company lawyer providing legal advice
14095
- USE BROWSER
14096
- KNOWLEDGE Corporate law and legal procedures
14097
- RULE Always recommend consulting with a licensed attorney for specific legal matters
14098
- \`\`\`
14099
- `);
14100
- }
14101
- /**
14102
- * Gets human-readable titles for tool functions provided by this commitment.
14103
- */
14104
- getToolTitles() {
14105
- return {
14106
- fetch_url_content: 'Fetch URL content',
14107
- run_browser: 'Run browser',
14108
- };
14109
- }
14110
- applyToAgentModelRequirements(requirements, content) {
14111
- // Get existing tools array or create new one
14112
- const existingTools = requirements.tools || [];
14113
- // Add browser tools if not already present
14114
- const toolsToAdd = [];
14115
- // Tool 1: One-shot URL content fetching
14116
- if (!existingTools.some((tool) => tool.name === 'fetch_url_content')) {
14117
- toolsToAdd.push({
14118
- name: 'fetch_url_content',
14119
- description: spacetrim.spaceTrim(`
14120
- Fetches and scrapes the content from a URL (webpage or document).
14121
- This tool retrieves the content of the specified URL and converts it to markdown format.
14122
- Use this when you need to access information from a specific website or document.
14123
- Supports various content types including HTML pages and PDF documents.
14124
- `),
14125
- parameters: {
14126
- type: 'object',
14127
- properties: {
14128
- url: {
14129
- type: 'string',
14130
- description: 'The URL to fetch and scrape (e.g., "https://example.com" or "https://example.com/document.pdf")',
14131
- },
14132
- },
14133
- required: ['url'],
14134
- },
14135
- });
14136
- }
14137
- // Tool 2: Running browser for complex page interactions
14138
- if (!existingTools.some((tool) => tool.name === 'run_browser')) {
14139
- toolsToAdd.push({
14140
- name: 'run_browser',
14141
- description: spacetrim.spaceTrim(`
14142
- Launches a browser session for complex interactions.
14143
- This tool is for advanced browser automation tasks like scrolling, clicking, form filling, etc.
14144
- Use this when simple one-shot URL fetching is not enough.
14145
- `),
14146
- parameters: {
14147
- type: 'object',
14148
- properties: {
14149
- url: {
14150
- type: 'string',
14151
- description: 'The initial URL to navigate to',
14152
- },
14153
- actions: {
14154
- type: 'array',
14155
- description: 'Array of actions to perform in the browser',
14156
- items: {
14157
- type: 'object',
14158
- properties: {
14159
- type: {
14160
- type: 'string',
14161
- enum: ['navigate', 'click', 'scroll', 'type', 'wait'],
14162
- },
14163
- selector: {
14164
- type: 'string',
14165
- description: 'CSS selector for the element (for click, type actions)',
14166
- },
14167
- value: {
14168
- type: 'string',
14169
- description: 'Value to type or navigate to',
14170
- },
14171
- },
14172
- },
14173
- },
14174
- },
14175
- required: ['url'],
14176
- },
14177
- });
14178
- }
14179
- const updatedTools = [...existingTools, ...toolsToAdd];
14180
- return appendAggregatedUseCommitmentPlaceholder({
14181
- ...requirements,
14182
- tools: updatedTools,
14183
- _metadata: {
14184
- ...requirements._metadata,
14185
- useBrowser: true,
14186
- },
14187
- }, this.type);
14188
- }
14189
- /**
14190
- * Gets the browser tool function implementations.
14191
- *
14192
- * This method automatically detects the environment and uses:
14193
- * - Server-side: Direct scraping via fetchUrlContent (Node.js)
14194
- * - Browser: Proxy through Agents Server API via fetchUrlContentViaBrowser
14195
- */
14196
- getToolFunctions() {
14197
- return {
14198
- /**
14199
- * @@@
14200
- *
14201
- * Note: [🛺] This function has implementation both for browser and node, this is the proxied one for browser
14202
- */
14203
- async fetch_url_content(args) {
14204
- console.log('!!!! [Tool] fetch_url_content called', { args });
14205
- const { url } = args;
14206
- return await fetchUrlContentViaBrowser(url);
14207
- },
14208
- /**
14209
- * @@@
14210
- */
14211
- async run_browser(args) {
14212
- console.log('!!!! [Tool] run_browser called', { args });
14213
- const { url } = args;
14214
- return spacetrim.spaceTrim(`
14215
- # Running browser
14216
-
14217
- The running browser tool is not available in this runtime.
14218
-
14219
- This environment does not provide the server-side browser automation backend.
14220
- In Agents Server Node runtime, this tool is resolved to a Playwright CLI implementation.
14221
-
14222
- Requested URL: ${url}
14223
- `);
14224
- },
14225
- };
13251
+ function formatOptionalInstructionBlock(label, content) {
13252
+ const trimmedContent = spacetrim.spaceTrim(content);
13253
+ if (!trimmedContent) {
13254
+ return '';
14226
13255
  }
13256
+ return spacetrim.spaceTrim((block) => `
13257
+ - ${label}:
13258
+ ${block(trimmedContent
13259
+ .split(/\r?\n/)
13260
+ .map((line) => `- ${line}`)
13261
+ .join('\n'))}
13262
+ `);
14227
13263
  }
14228
- // Note: [💞] Ignore a discrepancy between file name and entity name
14229
13264
 
14230
13265
  /**
14231
13266
  * Hostnames accepted for Google Calendar references.
@@ -14550,7 +13585,7 @@
14550
13585
  const runtimeContext = (readToolRuntimeContextFromToolArgs(args) ||
14551
13586
  {});
14552
13587
  const configuredCalendars = normalizeConfiguredCalendars$1((_a = runtimeContext.calendars) === null || _a === void 0 ? void 0 : _a.connections);
14553
- const calendarArgument = normalizeOptionalText$2(args.calendarUrl);
13588
+ const calendarArgument = normalizeOptionalText$1(args.calendarUrl);
14554
13589
  let calendarReference = null;
14555
13590
  if (calendarArgument) {
14556
13591
  calendarReference = parseGoogleCalendarReference(calendarArgument);
@@ -14570,7 +13605,7 @@
14570
13605
  if (!calendarReference) {
14571
13606
  throw new Error('Calendar is required but was not resolved.');
14572
13607
  }
14573
- const accessToken = normalizeOptionalText$2((_b = runtimeContext.calendars) === null || _b === void 0 ? void 0 : _b.googleAccessToken) || '';
13608
+ const accessToken = normalizeOptionalText$1((_b = runtimeContext.calendars) === null || _b === void 0 ? void 0 : _b.googleAccessToken) || '';
14574
13609
  if (!accessToken) {
14575
13610
  throw new CalendarWalletCredentialRequiredError({
14576
13611
  calendarReference,
@@ -14603,7 +13638,7 @@
14603
13638
  continue;
14604
13639
  }
14605
13640
  const calendar = rawCalendar;
14606
- const rawUrl = normalizeOptionalText$2(calendar.url);
13641
+ const rawUrl = normalizeOptionalText$1(calendar.url);
14607
13642
  if (!rawUrl) {
14608
13643
  continue;
14609
13644
  }
@@ -14654,7 +13689,7 @@
14654
13689
  *
14655
13690
  * @private function of resolveUseCalendarToolRuntimeOrWalletCredentialResult
14656
13691
  */
14657
- function normalizeOptionalText$2(value) {
13692
+ function normalizeOptionalText$1(value) {
14658
13693
  if (typeof value !== 'string') {
14659
13694
  return undefined;
14660
13695
  }
@@ -14686,13 +13721,13 @@
14686
13721
  async [UseCalendarToolNames.listEvents](args) {
14687
13722
  return withUseCalendarRuntime(args, async ({ calendarReference, accessToken }) => {
14688
13723
  const query = {};
14689
- if (normalizeOptionalText$1(args.timeMin)) {
13724
+ if (normalizeOptionalText(args.timeMin)) {
14690
13725
  query.timeMin = args.timeMin.trim();
14691
13726
  }
14692
- if (normalizeOptionalText$1(args.timeMax)) {
13727
+ if (normalizeOptionalText(args.timeMax)) {
14693
13728
  query.timeMax = args.timeMax.trim();
14694
13729
  }
14695
- if (normalizeOptionalText$1(args.query)) {
13730
+ if (normalizeOptionalText(args.query)) {
14696
13731
  query.q = args.query.trim();
14697
13732
  }
14698
13733
  if (typeof args.maxResults === 'number' && Number.isFinite(args.maxResults) && args.maxResults > 0) {
@@ -14704,7 +13739,7 @@
14704
13739
  if (args.orderBy === 'startTime' || args.orderBy === 'updated') {
14705
13740
  query.orderBy = args.orderBy;
14706
13741
  }
14707
- if (normalizeOptionalText$1(args.timeZone)) {
13742
+ if (normalizeOptionalText(args.timeZone)) {
14708
13743
  query.timeZone = args.timeZone.trim();
14709
13744
  }
14710
13745
  const payload = await callGoogleCalendarApi(accessToken, {
@@ -14742,11 +13777,11 @@
14742
13777
  return withUseCalendarRuntime(args, async ({ calendarReference, accessToken }) => {
14743
13778
  const requestBody = createGoogleCalendarEventPayload({
14744
13779
  summary: normalizeRequiredText(args.summary, 'summary'),
14745
- description: normalizeOptionalText$1(args.description),
14746
- location: normalizeOptionalText$1(args.location),
13780
+ description: normalizeOptionalText(args.description),
13781
+ location: normalizeOptionalText(args.location),
14747
13782
  start: normalizeRequiredText(args.start, 'start'),
14748
13783
  end: normalizeRequiredText(args.end, 'end'),
14749
- timeZone: normalizeOptionalText$1(args.timeZone),
13784
+ timeZone: normalizeOptionalText(args.timeZone),
14750
13785
  attendees: normalizeAttendees(args.attendees),
14751
13786
  reminderMinutes: normalizeReminderMinutes(args.reminderMinutes),
14752
13787
  });
@@ -14768,12 +13803,12 @@
14768
13803
  return withUseCalendarRuntime(args, async ({ calendarReference, accessToken }) => {
14769
13804
  const eventId = normalizeRequiredText(args.eventId, 'eventId');
14770
13805
  const requestBody = createGoogleCalendarEventPayload({
14771
- summary: normalizeOptionalText$1(args.summary),
14772
- description: normalizeOptionalText$1(args.description),
14773
- location: normalizeOptionalText$1(args.location),
14774
- start: normalizeOptionalText$1(args.start),
14775
- end: normalizeOptionalText$1(args.end),
14776
- timeZone: normalizeOptionalText$1(args.timeZone),
13806
+ summary: normalizeOptionalText(args.summary),
13807
+ description: normalizeOptionalText(args.description),
13808
+ location: normalizeOptionalText(args.location),
13809
+ start: normalizeOptionalText(args.start),
13810
+ end: normalizeOptionalText(args.end),
13811
+ timeZone: normalizeOptionalText(args.timeZone),
14777
13812
  attendees: normalizeAttendees(args.attendees),
14778
13813
  reminderMinutes: normalizeReminderMinutes(args.reminderMinutes),
14779
13814
  });
@@ -14820,7 +13855,7 @@
14820
13855
  path: `/calendars/${encodeGoogleCalendarId(calendarReference.calendarId)}/events/${encodeURIComponent(eventId)}`,
14821
13856
  });
14822
13857
  const existingAttendees = ((existingEvent === null || existingEvent === void 0 ? void 0 : existingEvent.attendees) || [])
14823
- .map((attendee) => normalizeOptionalText$1(attendee.email))
13858
+ .map((attendee) => normalizeOptionalText(attendee.email))
14824
13859
  .filter((email) => Boolean(email));
14825
13860
  const mergedAttendees = [...new Set([...existingAttendees, ...guests])];
14826
13861
  const payload = await callGoogleCalendarApi(accessToken, {
@@ -14868,7 +13903,7 @@
14868
13903
  * @private function of createUseCalendarToolFunctions
14869
13904
  */
14870
13905
  function normalizeRequiredText(value, fieldName) {
14871
- const normalizedValue = normalizeOptionalText$1(value);
13906
+ const normalizedValue = normalizeOptionalText(value);
14872
13907
  if (!normalizedValue) {
14873
13908
  throw new Error(`Tool "${fieldName}" requires non-empty value.`);
14874
13909
  }
@@ -14879,7 +13914,7 @@
14879
13914
  *
14880
13915
  * @private function of createUseCalendarToolFunctions
14881
13916
  */
14882
- function normalizeOptionalText$1(value) {
13917
+ function normalizeOptionalText(value) {
14883
13918
  if (typeof value !== 'string') {
14884
13919
  return undefined;
14885
13920
  }
@@ -15453,484 +14488,6 @@
15453
14488
  }
15454
14489
  // Note: [💞] Ignore a discrepancy between file name and entity name
15455
14490
 
15456
- /**
15457
- * A search engine implementation that uses the SerpApi to fetch Google search results.
15458
- *
15459
- * @private <- TODO: !!!! Export via some package
15460
- */
15461
- class SerpSearchEngine {
15462
- get title() {
15463
- return 'SerpApi Search Engine';
15464
- }
15465
- get description() {
15466
- return 'Search engine that uses SerpApi to fetch Google search results';
15467
- }
15468
- checkConfiguration() {
15469
- if (!process.env.SERP_API_KEY) {
15470
- throw new Error('SERP_API_KEY is not configured');
15471
- }
15472
- }
15473
- async search(query, options = {}) {
15474
- const apiKey = process.env.SERP_API_KEY;
15475
- if (!apiKey) {
15476
- throw new Error('SERP_API_KEY is not configured');
15477
- }
15478
- const url = new URL('https://serpapi.com/search');
15479
- url.searchParams.set('api_key', apiKey);
15480
- url.searchParams.set('engine', 'google');
15481
- url.searchParams.set('q', query);
15482
- for (const [key, value] of Object.entries(options)) {
15483
- url.searchParams.set(key, String(value));
15484
- }
15485
- const response = await fetch(url.toString());
15486
- if (!response.ok) {
15487
- const body = await response.text();
15488
- throw new Error(`SerpApi failed with status ${response.status}: ${response.statusText}\n${body}`);
15489
- }
15490
- const data = (await response.json());
15491
- return (data.organic_results || []).map((item) => ({
15492
- title: item.title,
15493
- url: item.link,
15494
- snippet: item.snippet || '',
15495
- }));
15496
- }
15497
- }
15498
-
15499
- /**
15500
- * Creates one SERP-backed tool function used as a local fallback for search-like commitments.
15501
- *
15502
- * @param toolName - Technical tool name used for validation messages.
15503
- * @param resultLabel - Human-readable label used in formatted results.
15504
- * @returns Async tool function compatible with commitment tool registration.
15505
- *
15506
- * @private internal helper for search-like commitments
15507
- */
15508
- function createSerpSearchToolFunction(toolName, resultLabel) {
15509
- return async (rawArgs) => {
15510
- const { query, ...searchOptions } = rawArgs;
15511
- if (typeof query !== 'string' || !query.trim()) {
15512
- throw new Error(`${toolName} query is required`);
15513
- }
15514
- const searchEngine = new SerpSearchEngine();
15515
- const results = await searchEngine.search(query, searchOptions);
15516
- return spacetrim.spaceTrim((block) => `
15517
- ${resultLabel} results for "${query}"${Object.keys(searchOptions).length === 0 ? '' : ` with options ${JSON.stringify(searchOptions)}`}:
15518
-
15519
- ${block(results
15520
- .map((result) => spacetrim.spaceTrim(`
15521
- - **${result.title}**
15522
- ${result.url}
15523
- ${result.snippet}
15524
- `))
15525
- .join('\n\n'))}
15526
- `);
15527
- };
15528
- }
15529
-
15530
- /**
15531
- * USE DEEPSEARCH commitment definition
15532
- *
15533
- * The `USE DEEPSEARCH` commitment indicates that the agent should use a deeper research-oriented
15534
- * search workflow instead of lightweight web search when it needs fresh information from the internet.
15535
- *
15536
- * The content following `USE DEEPSEARCH` is an arbitrary text that the agent should know
15537
- * (e.g. search scope or research instructions).
15538
- *
15539
- * Example usage in agent source:
15540
- *
15541
- * ```book
15542
- * USE DEEPSEARCH
15543
- * USE DEEPSEARCH Compare official vendor documentation with independent benchmarks.
15544
- * ```
15545
- *
15546
- * @private [🪔] Maybe export the commitments through some package
15547
- */
15548
- class UseDeepSearchCommitmentDefinition extends BaseCommitmentDefinition {
15549
- constructor() {
15550
- super('USE DEEPSEARCH');
15551
- }
15552
- get requiresContent() {
15553
- return false;
15554
- }
15555
- /**
15556
- * Short one-line description of USE DEEPSEARCH.
15557
- */
15558
- get description() {
15559
- return 'Enable the agent to use DeepSearch for more thorough internet research.';
15560
- }
15561
- /**
15562
- * Icon for this commitment.
15563
- */
15564
- get icon() {
15565
- return '🔬';
15566
- }
15567
- /**
15568
- * Markdown documentation for USE DEEPSEARCH commitment.
15569
- */
15570
- get documentation() {
15571
- return spacetrim.spaceTrim(`
15572
- # USE DEEPSEARCH
15573
-
15574
- Enables the agent to use DeepSearch for broader, more thorough internet research than lightweight web search.
15575
-
15576
- ## Key aspects
15577
-
15578
- - The content following \`USE DEEPSEARCH\` is arbitrary guidance for the research workflow.
15579
- - In Agents Server, the OpenAI Agents SDK runtime uses a nested deep-research agent for this tool.
15580
- - Use this for investigations, comparisons, market scans, or other tasks that benefit from deeper synthesis.
15581
- - Prefer regular \`USE SEARCH ENGINE\` when a quick factual lookup is enough.
15582
-
15583
- ## Examples
15584
-
15585
- \`\`\`book
15586
- Due Diligence Researcher
15587
-
15588
- GOAL Investigate vendors thoroughly before making recommendations.
15589
- USE DEEPSEARCH Compare official sources with credible third-party analysis.
15590
- RULE Cite the strongest supporting sources in the final answer.
15591
- \`\`\`
15592
-
15593
- \`\`\`book
15594
- Market Analyst
15595
-
15596
- GOAL Build concise but well-grounded research briefs.
15597
- USE DEEPSEARCH Focus on recent public information and competing viewpoints.
15598
- CLOSED
15599
- \`\`\`
15600
- `);
15601
- }
15602
- applyToAgentModelRequirements(requirements, content) {
15603
- const existingTools = requirements.tools || [];
15604
- const updatedTools = existingTools.some((tool) => tool.name === 'deep_search')
15605
- ? existingTools
15606
- : [
15607
- ...existingTools,
15608
- {
15609
- name: 'deep_search',
15610
- description: spacetrim.spaceTrim(`
15611
- Research the internet deeply and synthesize a grounded answer.
15612
- Use this tool for broader investigations, comparisons, and requests that need more than a quick search.
15613
- `),
15614
- parameters: {
15615
- type: 'object',
15616
- properties: {
15617
- query: {
15618
- type: 'string',
15619
- description: 'The research question or investigation request.',
15620
- },
15621
- },
15622
- required: ['query'],
15623
- additionalProperties: false,
15624
- },
15625
- },
15626
- ];
15627
- return appendAggregatedUseCommitmentPlaceholder({
15628
- ...requirements,
15629
- tools: updatedTools,
15630
- _metadata: {
15631
- ...requirements._metadata,
15632
- useDeepSearch: content || true,
15633
- },
15634
- }, this.type);
15635
- }
15636
- /**
15637
- * Gets human-readable titles for tool functions provided by this commitment.
15638
- */
15639
- getToolTitles() {
15640
- return {
15641
- deep_search: 'DeepSearch',
15642
- };
15643
- }
15644
- /**
15645
- * Gets the local fallback implementation for the `deep_search` tool.
15646
- */
15647
- getToolFunctions() {
15648
- return {
15649
- deep_search: createSerpSearchToolFunction('deep_search', 'DeepSearch'),
15650
- };
15651
- }
15652
- }
15653
- // Note: [💞] Ignore a discrepancy between file name and entity name
15654
-
15655
- /**
15656
- * Checks if value is valid email
15657
- *
15658
- * @public exported from `@promptbook/utils`
15659
- */
15660
- function isValidEmail(email) {
15661
- if (typeof email !== 'string') {
15662
- return false;
15663
- }
15664
- if (email.split(/\r?\n/).length > 1) {
15665
- return false;
15666
- }
15667
- return /^.+@.+\..+$/.test(email);
15668
- }
15669
-
15670
- /**
15671
- * Lightweight email token matcher used for `USE EMAIL` first-line parsing.
15672
- *
15673
- * @private internal USE EMAIL constant
15674
- */
15675
- const EMAIL_TOKEN_PATTERN = /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/;
15676
- /**
15677
- * Parses `USE EMAIL` commitment content into optional sender email + additional instructions.
15678
- *
15679
- * Examples:
15680
- * - `agent@example.com`
15681
- * - `agent@example.com Keep emails concise`
15682
- * - `Keep emails concise`
15683
- *
15684
- * @private internal utility of USE EMAIL commitment
15685
- */
15686
- function parseUseEmailCommitmentContent(content) {
15687
- const trimmedContent = spacetrim.spaceTrim(content);
15688
- if (!trimmedContent) {
15689
- return {
15690
- senderEmail: null,
15691
- senderEmailRaw: null,
15692
- instructions: '',
15693
- };
15694
- }
15695
- const lines = trimmedContent
15696
- .split(/\r?\n/)
15697
- .map((line) => line.trim())
15698
- .filter(Boolean);
15699
- if (lines.length === 0) {
15700
- return {
15701
- senderEmail: null,
15702
- senderEmailRaw: null,
15703
- instructions: '',
15704
- };
15705
- }
15706
- const firstLine = lines[0] || '';
15707
- const senderMatch = firstLine.match(EMAIL_TOKEN_PATTERN);
15708
- const senderEmailRaw = (senderMatch === null || senderMatch === void 0 ? void 0 : senderMatch[0]) || null;
15709
- const senderEmail = senderEmailRaw && isValidEmail(senderEmailRaw) ? senderEmailRaw : null;
15710
- let firstLineWithoutSender = firstLine;
15711
- if (senderEmailRaw) {
15712
- const matchIndex = firstLine.indexOf(senderEmailRaw);
15713
- const prefix = firstLine.slice(0, matchIndex).trim();
15714
- const suffix = firstLine.slice(matchIndex + senderEmailRaw.length).trim();
15715
- firstLineWithoutSender = [prefix, suffix].filter(Boolean).join(' ').trim();
15716
- }
15717
- const instructionLines = [firstLineWithoutSender, ...lines.slice(1)].filter(Boolean);
15718
- const instructions = instructionLines.join('\n').trim();
15719
- return {
15720
- senderEmail,
15721
- senderEmailRaw,
15722
- instructions,
15723
- };
15724
- }
15725
-
15726
- /**
15727
- * Client-side safe wrapper for sending emails.
15728
- *
15729
- * This function proxies requests to the Agents Server API endpoint for email queuing,
15730
- * making it safe to use in browser environments.
15731
- *
15732
- * @param args Email payload forwarded to the server-side `send_email` tool
15733
- * @param agentsServerUrl The base URL of the agents server (defaults to current origin)
15734
- * @returns Result string from the server-side send_email tool
15735
- *
15736
- * @private internal utility for USE EMAIL commitment
15737
- */
15738
- async function sendEmailViaBrowser(args, agentsServerUrl) {
15739
- try {
15740
- const baseUrl = agentsServerUrl || (typeof window !== 'undefined' ? window.location.origin : '');
15741
- if (!baseUrl) {
15742
- throw new Error('Agents server URL is required in non-browser environments');
15743
- }
15744
- const apiUrl = new URL('/api/send-email', baseUrl);
15745
- const response = await fetch(apiUrl.toString(), {
15746
- method: 'POST',
15747
- headers: {
15748
- 'Content-Type': 'application/json',
15749
- },
15750
- body: JSON.stringify(args),
15751
- });
15752
- if (!response.ok) {
15753
- const errorData = await response.json().catch(() => ({ error: 'Unknown error' }));
15754
- throw new Error(`Failed to send email: ${errorData.error || response.statusText}`);
15755
- }
15756
- const data = await response.json();
15757
- if (!data.success) {
15758
- throw new Error(`Email sending failed: ${data.error || 'Unknown error'}`);
15759
- }
15760
- return typeof data.result === 'string' ? data.result : JSON.stringify(data.result);
15761
- }
15762
- catch (error) {
15763
- const errorMessage = error instanceof Error ? error.message : String(error);
15764
- throw new Error(`Error sending email via browser: ${errorMessage}`);
15765
- }
15766
- }
15767
-
15768
- /**
15769
- * Tool name used by USE EMAIL.
15770
- *
15771
- * @private internal USE EMAIL constant
15772
- */
15773
- const SEND_EMAIL_TOOL_NAME = 'send_email';
15774
- /**
15775
- * USE EMAIL commitment definition.
15776
- *
15777
- * The `USE EMAIL` commitment enables outbound email sending through the `send_email` tool.
15778
- *
15779
- * @private [🪔] Maybe export the commitments through some package
15780
- */
15781
- class UseEmailCommitmentDefinition extends BaseCommitmentDefinition {
15782
- constructor() {
15783
- super('USE EMAIL', ['EMAIL', 'MAIL']);
15784
- }
15785
- get requiresContent() {
15786
- return false;
15787
- }
15788
- /**
15789
- * Short one-line description of USE EMAIL.
15790
- */
15791
- get description() {
15792
- return 'Enable outbound email sending through a wallet-backed SMTP configuration.';
15793
- }
15794
- /**
15795
- * Icon for this commitment.
15796
- */
15797
- get icon() {
15798
- return '📧';
15799
- }
15800
- /**
15801
- * Markdown documentation for USE EMAIL commitment.
15802
- */
15803
- get documentation() {
15804
- return spacetrim.spaceTrim(`
15805
- # USE EMAIL
15806
-
15807
- Enables the agent to send outbound emails through SMTP.
15808
-
15809
- ## Key aspects
15810
-
15811
- - The agent sends email via the \`send_email\` tool.
15812
- - SMTP credentials are expected from wallet records (\`ACCESS_TOKEN\`, service \`smtp\`, key \`use-email-smtp-credentials\`).
15813
- - Commitment content can optionally begin with a default sender email address:
15814
- - \`USE EMAIL agent@example.com\`
15815
- - Remaining commitment content is treated as optional email-writing instructions.
15816
-
15817
- ## Examples
15818
-
15819
- \`\`\`book
15820
- Writing Agent
15821
- USE EMAIL agent@example.com
15822
- RULE Write emails to customers according to the instructions from user.
15823
- \`\`\`
15824
-
15825
- \`\`\`book
15826
- Formal Email Assistant
15827
- USE EMAIL agent@example.com Keep emails concise and formal.
15828
- \`\`\`
15829
- `);
15830
- }
15831
- applyToAgentModelRequirements(requirements, content) {
15832
- var _a;
15833
- const parsedCommitment = parseUseEmailCommitmentContent(content);
15834
- const updatedTools = addUseEmailTools(requirements.tools || []);
15835
- // Collect all configured sender emails across multiple USE EMAIL commitments
15836
- const existingSenders = Array.isArray((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.useEmailSenders)
15837
- ? [...requirements._metadata.useEmailSenders]
15838
- : [];
15839
- if (parsedCommitment.senderEmail && !existingSenders.includes(parsedCommitment.senderEmail)) {
15840
- existingSenders.push(parsedCommitment.senderEmail);
15841
- }
15842
- const senderBullets = existingSenders.length > 0
15843
- ? existingSenders
15844
- .map((email, index) => index === 0
15845
- ? `- Default sender address: "${email}".`
15846
- : `- Additional sender address: "${email}".`)
15847
- .join('\n')
15848
- : '';
15849
- const extraInstructions = formatOptionalInstructionBlock('Email instructions', parsedCommitment.instructions);
15850
- const emailSectionContent = spacetrim.spaceTrim((block) => `
15851
- ## Emails
15852
-
15853
- - Use \`${SEND_EMAIL_TOOL_NAME}\` to send outbound emails.
15854
- ${block(senderBullets)}
15855
- ${block(extraInstructions)}
15856
- `);
15857
- return this.replaceOrCreateSection({
15858
- ...requirements,
15859
- tools: updatedTools,
15860
- _metadata: {
15861
- ...requirements._metadata,
15862
- useEmail: true,
15863
- ...(parsedCommitment.senderEmail ? { useEmailSender: parsedCommitment.senderEmail } : {}),
15864
- useEmailSenders: existingSenders,
15865
- },
15866
- }, 'Emails', emailSectionContent);
15867
- }
15868
- /**
15869
- * Gets human-readable titles for tool functions provided by this commitment.
15870
- */
15871
- getToolTitles() {
15872
- return {
15873
- [SEND_EMAIL_TOOL_NAME]: 'Send email',
15874
- };
15875
- }
15876
- /**
15877
- * Gets the browser-safe `send_email` implementation.
15878
- *
15879
- * Node.js runtime overrides this via `getAllCommitmentsToolFunctionsForNode`.
15880
- */
15881
- getToolFunctions() {
15882
- return {
15883
- async [SEND_EMAIL_TOOL_NAME](args) {
15884
- return sendEmailViaBrowser(args);
15885
- },
15886
- };
15887
- }
15888
- }
15889
- /**
15890
- * Adds USE EMAIL tool definition while keeping already registered tools untouched.
15891
- *
15892
- * @private utility of USE EMAIL commitment
15893
- */
15894
- function addUseEmailTools(existingTools) {
15895
- if (existingTools.some((tool) => tool.name === SEND_EMAIL_TOOL_NAME)) {
15896
- return [...existingTools];
15897
- }
15898
- return [
15899
- ...existingTools,
15900
- {
15901
- name: SEND_EMAIL_TOOL_NAME,
15902
- description: 'Send an outbound email.',
15903
- parameters: {
15904
- type: 'object',
15905
- properties: {
15906
- message: {
15907
- type: 'object',
15908
- description: 'Email payload. Use metadata.subject for the subject line.',
15909
- },
15910
- to: {
15911
- type: 'string',
15912
- description: 'Legacy alias for recipients (use comma-separated emails or JSON array encoded as string).',
15913
- },
15914
- cc: {
15915
- type: 'string',
15916
- description: 'Optional CC recipients (use comma-separated emails or JSON array encoded as string).',
15917
- },
15918
- subject: {
15919
- type: 'string',
15920
- description: 'Legacy alias for subject.',
15921
- },
15922
- body: {
15923
- type: 'string',
15924
- description: 'Legacy alias for markdown body content.',
15925
- },
15926
- },
15927
- required: [],
15928
- },
15929
- },
15930
- ];
15931
- }
15932
- // Note: [💞] Ignore a discrepancy between file name and entity name
15933
-
15934
14491
  /**
15935
14492
  * USE IMAGE GENERATOR commitment definition
15936
14493
  *
@@ -18159,1503 +16716,6 @@
18159
16716
  }
18160
16717
  // Note: [💞] Ignore a discrepancy between file name and entity name
18161
16718
 
18162
- /**
18163
- * USE SEARCH ENGINE commitment definition
18164
- *
18165
- * The `USE SEARCH ENGINE` commitment indicates that the agent should utilize a search engine tool
18166
- * to access and retrieve up-to-date information from the internet when necessary.
18167
- *
18168
- * The content following `USE SEARCH ENGINE` is an arbitrary text that the agent should know (e.g. search scope or instructions).
18169
- *
18170
- * Example usage in agent source:
18171
- *
18172
- * ```book
18173
- * USE SEARCH ENGINE
18174
- * USE SEARCH ENGINE Hledej informace o Přemyslovcích
18175
- * ```
18176
- *
18177
- * @private [🪔] Maybe export the commitments through some package
18178
- */
18179
- class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
18180
- constructor() {
18181
- super('USE SEARCH ENGINE', ['USE SEARCH']);
18182
- }
18183
- get requiresContent() {
18184
- return false;
18185
- }
18186
- /**
18187
- * Short one-line description of USE SEARCH ENGINE.
18188
- */
18189
- get description() {
18190
- return 'Enable the agent to use a search engine tool for accessing internet information.';
18191
- }
18192
- /**
18193
- * Icon for this commitment.
18194
- */
18195
- get icon() {
18196
- return '🔍';
18197
- }
18198
- /**
18199
- * Markdown documentation for USE SEARCH ENGINE commitment.
18200
- */
18201
- get documentation() {
18202
- return spacetrim.spaceTrim(`
18203
- # USE SEARCH ENGINE
18204
-
18205
- Enables the agent to use a search engine tool to access and retrieve up-to-date information from the internet.
18206
-
18207
- ## Key aspects
18208
-
18209
- - The content following \`USE SEARCH ENGINE\` is an arbitrary text that the agent should know (e.g. search scope or instructions).
18210
- - The actual search engine tool usage is handled by the agent runtime
18211
- - Allows the agent to search for current information from the web
18212
- - Useful for research tasks, finding facts, and accessing dynamic content
18213
-
18214
- ## Examples
18215
-
18216
- \`\`\`book
18217
- Research Assistant
18218
-
18219
- PERSONA You are a helpful research assistant specialized in finding current information
18220
- USE SEARCH ENGINE
18221
- RULE Always cite your sources when providing information from the web
18222
- \`\`\`
18223
-
18224
- \`\`\`book
18225
- Fact Checker
18226
-
18227
- PERSONA You are a fact checker
18228
- USE SEARCH ENGINE
18229
- ACTION Search for claims and verify them against reliable sources
18230
- \`\`\`
18231
- `);
18232
- }
18233
- applyToAgentModelRequirements(requirements, content) {
18234
- // Get existing tools array or create new one
18235
- const existingTools = requirements.tools || [];
18236
- // Add 'web_search' to tools if not already present
18237
- const updatedTools = existingTools.some((tool) => tool.name === 'web_search')
18238
- ? existingTools
18239
- : [
18240
- ...existingTools,
18241
- {
18242
- name: 'web_search',
18243
- description: spacetrim.spaceTrim(`
18244
- Search the internet for information.
18245
- Use this tool when you need to find up-to-date information or facts that you don't know.
18246
- `),
18247
- parameters: {
18248
- type: 'object',
18249
- properties: {
18250
- query: {
18251
- type: 'string',
18252
- description: 'The search query',
18253
- },
18254
- location: {
18255
- type: 'string',
18256
- description: 'The location for the search (e.g., "Austin, Texas, United States" or "Prague, Czechia")',
18257
- },
18258
- gl: {
18259
- type: 'string',
18260
- description: 'The country code (e.g., "us" for United States, "cz" for Czechia)',
18261
- },
18262
- hl: {
18263
- type: 'string',
18264
- description: 'The language code (e.g., "en" for English, "cs" for Czech)',
18265
- },
18266
- num: {
18267
- type: 'integer',
18268
- description: 'Number of results to return',
18269
- },
18270
- engine: {
18271
- type: 'string',
18272
- description: 'The search engine to use (e.g., "google", "bing", "yahoo", "baidu")',
18273
- },
18274
- google_domain: {
18275
- type: 'string',
18276
- description: 'The Google domain to use (e.g., "google.com", "google.cz")',
18277
- },
18278
- },
18279
- required: ['query'],
18280
- },
18281
- },
18282
- ];
18283
- return appendAggregatedUseCommitmentPlaceholder({
18284
- ...requirements,
18285
- tools: updatedTools,
18286
- _metadata: {
18287
- ...requirements._metadata,
18288
- useSearchEngine: content || true,
18289
- },
18290
- }, this.type);
18291
- }
18292
- /**
18293
- * Gets human-readable titles for tool functions provided by this commitment.
18294
- */
18295
- getToolTitles() {
18296
- return {
18297
- web_search: 'Web search',
18298
- };
18299
- }
18300
- /**
18301
- * Gets the `web_search` tool function implementation.
18302
- */
18303
- getToolFunctions() {
18304
- return {
18305
- web_search: createSerpSearchToolFunction('web_search', 'Search'),
18306
- };
18307
- }
18308
- }
18309
- // Note: [💞] Ignore a discrepancy between file name and entity name
18310
-
18311
- /**
18312
- * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
18313
- *
18314
- * @public exported from `@promptbook/core`
18315
- */
18316
- class ParseError extends Error {
18317
- constructor(message) {
18318
- super(message);
18319
- this.name = 'ParseError';
18320
- Object.setPrototypeOf(this, ParseError.prototype);
18321
- }
18322
- }
18323
- // TODO: Maybe split `ParseError` and `ApplyError`
18324
-
18325
- /**
18326
- * Supported visibility states for persisted agents.
18327
- *
18328
- * @public exported from `@promptbook/core`
18329
- */
18330
- const AGENT_VISIBILITY_VALUES = ['PRIVATE', 'UNLISTED', 'PUBLIC'];
18331
- /**
18332
- * Returns `true` when the value is one of supported visibility states.
18333
- *
18334
- * @param value - Raw value to validate.
18335
- * @returns Whether the value is a valid `AgentVisibility`.
18336
- *
18337
- * @public exported from `@promptbook/core`
18338
- */
18339
- function isAgentVisibility(value) {
18340
- return typeof value === 'string' && AGENT_VISIBILITY_VALUES.includes(value);
18341
- }
18342
- /**
18343
- * Normalizes raw visibility text into a supported value.
18344
- *
18345
- * @param value - Raw visibility value.
18346
- * @returns Normalized visibility, or `null` when invalid.
18347
- *
18348
- * @public exported from `@promptbook/core`
18349
- */
18350
- function normalizeAgentVisibility(value) {
18351
- if (typeof value !== 'string') {
18352
- return null;
18353
- }
18354
- const normalized = value.trim().toUpperCase();
18355
- return isAgentVisibility(normalized) ? normalized : null;
18356
- }
18357
- // Note: [💞] Ignore a discrepancy between file name and entity name
18358
-
18359
- /**
18360
- * This error type indicates that some limit was reached
18361
- *
18362
- * @public exported from `@promptbook/core`
18363
- */
18364
- class LimitReachedError extends Error {
18365
- constructor(message) {
18366
- super(message);
18367
- this.name = 'LimitReachedError';
18368
- Object.setPrototypeOf(this, LimitReachedError.prototype);
18369
- }
18370
- }
18371
-
18372
- /**
18373
- * Maximum allowed source length for create-agent payloads.
18374
- *
18375
- * @private shared create-agent contract
18376
- */
18377
- const CREATE_AGENT_INPUT_SOURCE_MAX_LENGTH = 120000;
18378
- /**
18379
- * Builds strict JSON schema for create-agent tool parameters.
18380
- *
18381
- * @private shared create-agent contract
18382
- */
18383
- function createCreateAgentInputToolParametersSchema() {
18384
- return {
18385
- type: 'object',
18386
- additionalProperties: false,
18387
- properties: {
18388
- source: {
18389
- type: 'string',
18390
- description: 'Full source of the new persisted agent (Promptbook/book markdown).',
18391
- },
18392
- folderId: {
18393
- type: 'number',
18394
- description: 'Optional folder identifier where the new agent should be placed.',
18395
- },
18396
- sortOrder: {
18397
- type: 'number',
18398
- description: 'Optional sort order inside the selected folder.',
18399
- },
18400
- visibility: {
18401
- type: 'string',
18402
- description: 'Optional visibility: PRIVATE, UNLISTED, or PUBLIC.',
18403
- },
18404
- },
18405
- required: ['source'],
18406
- };
18407
- }
18408
-
18409
- /**
18410
- * Browser-safe wrapper for spawning one persisted Agents Server agent.
18411
- *
18412
- * This function proxies requests to the Agents Server `/api/spawn-agent` endpoint.
18413
- *
18414
- * @param args Tool payload forwarded to server-side `spawn_agent` tool.
18415
- * @param agentsServerUrl Optional explicit agents server base URL.
18416
- * @returns JSON string with structured spawn result.
18417
- *
18418
- * @private internal utility for USE SPAWN commitment
18419
- */
18420
- async function spawnAgentViaBrowser(args, agentsServerUrl) {
18421
- try {
18422
- const baseUrl = agentsServerUrl || (typeof window !== 'undefined' ? window.location.origin : '');
18423
- if (!baseUrl) {
18424
- throw new Error('Agents server URL is required in non-browser environments');
18425
- }
18426
- const apiUrl = new URL('/api/spawn-agent', baseUrl);
18427
- const response = await fetch(apiUrl.toString(), {
18428
- method: 'POST',
18429
- headers: {
18430
- 'Content-Type': 'application/json',
18431
- },
18432
- body: JSON.stringify(args),
18433
- });
18434
- const payload = (await response.json().catch(() => ({})));
18435
- if (payload.result !== undefined) {
18436
- return typeof payload.result === 'string' ? payload.result : JSON.stringify(payload.result);
18437
- }
18438
- if (!response.ok || payload.success === false) {
18439
- throw new Error(`Failed to spawn agent: ${typeof payload.error === 'string' ? payload.error : response.statusText}`);
18440
- }
18441
- return JSON.stringify(payload);
18442
- }
18443
- catch (error) {
18444
- const errorMessage = error instanceof Error ? error.message : String(error);
18445
- throw new Error(`Error spawning agent via browser: ${errorMessage}`);
18446
- }
18447
- }
18448
-
18449
- /**
18450
- * Tool name used by USE SPAWN.
18451
- *
18452
- * @private internal USE SPAWN constant
18453
- */
18454
- const SPAWN_AGENT_TOOL_NAME = 'spawn_agent';
18455
- /**
18456
- * USE SPAWN commitment definition.
18457
- *
18458
- * The `USE SPAWN` commitment enables creating new persistent child agents through one tool call.
18459
- *
18460
- * @private [🪔] Maybe export the commitments through some package
18461
- */
18462
- class UseSpawnCommitmentDefinition extends BaseCommitmentDefinition {
18463
- constructor() {
18464
- super('USE SPAWN', ['SPAWN']);
18465
- }
18466
- get requiresContent() {
18467
- return false;
18468
- }
18469
- /**
18470
- * Short one-line description of USE SPAWN.
18471
- */
18472
- get description() {
18473
- return 'Enable the agent to create persistent child agents via Agents Server create-agent flow.';
18474
- }
18475
- /**
18476
- * Icon for this commitment.
18477
- */
18478
- get icon() {
18479
- return '🧬';
18480
- }
18481
- /**
18482
- * Markdown documentation for USE SPAWN commitment.
18483
- */
18484
- get documentation() {
18485
- return spacetrim.spaceTrim(`
18486
- # USE SPAWN
18487
-
18488
- Enables the agent to create a new persistent child agent using the \`spawn_agent\` tool.
18489
-
18490
- ## Key aspects
18491
-
18492
- - The spawned agent is persisted exactly like manually created agents.
18493
- - Tool input mirrors create-agent fields currently supported by Agents Server:
18494
- - \`source\` (required)
18495
- - \`folderId\` (optional)
18496
- - \`sortOrder\` (optional)
18497
- - \`visibility\` (optional)
18498
- - Unknown fields are rejected to avoid silent misconfiguration.
18499
- - \`source\` payload is size-limited.
18500
- - Agents Server applies permission and abuse protections (auth checks, limits).
18501
- - Optional text after \`USE SPAWN\` is treated as spawn-policy instructions.
18502
-
18503
- ## Examples
18504
-
18505
- \`\`\`book
18506
- Team Builder
18507
-
18508
- PERSONA You can create specialized assistants for the user.
18509
- USE SPAWN Spawn only when the user explicitly asks for a new persistent agent.
18510
- \`\`\`
18511
- `);
18512
- }
18513
- applyToAgentModelRequirements(requirements, content) {
18514
- const extraInstructions = formatOptionalInstructionBlock('Spawn instructions', content);
18515
- const existingTools = requirements.tools || [];
18516
- const tools = existingTools.some((tool) => tool.name === SPAWN_AGENT_TOOL_NAME)
18517
- ? existingTools
18518
- : [
18519
- ...existingTools,
18520
- {
18521
- name: SPAWN_AGENT_TOOL_NAME,
18522
- description: spacetrim.spaceTrim(`
18523
- Creates one new persistent child agent in Agents Server.
18524
- Use this when the user asks to create a new dedicated agent profile.
18525
- The tool returns JSON with \`status\`, \`agentId\`, and created \`agent\` or \`error\`.
18526
- `),
18527
- parameters: createCreateAgentInputToolParametersSchema(),
18528
- },
18529
- ];
18530
- return this.appendToSystemMessage({
18531
- ...requirements,
18532
- tools,
18533
- _metadata: {
18534
- ...requirements._metadata,
18535
- useSpawn: content || true,
18536
- },
18537
- }, spacetrim.spaceTrim((block) => `
18538
- ## Spawning agents
18539
-
18540
- - Use \`${SPAWN_AGENT_TOOL_NAME}\` only when user asks to create a persistent new agent.
18541
- - Pass full agent source in \`source\`.
18542
- - Keep \`source\` concise; the maximum accepted length is ${CREATE_AGENT_INPUT_SOURCE_MAX_LENGTH} characters.
18543
- - Do not add unknown fields in tool arguments.
18544
- ${block(extraInstructions)}
18545
- `));
18546
- }
18547
- /**
18548
- * Gets human-readable titles for tool functions provided by this commitment.
18549
- */
18550
- getToolTitles() {
18551
- return {
18552
- [SPAWN_AGENT_TOOL_NAME]: 'Spawn agent',
18553
- };
18554
- }
18555
- /**
18556
- * Gets browser-safe `spawn_agent` implementation.
18557
- *
18558
- * Node.js runtime overrides this through `getAllCommitmentsToolFunctionsForNode`.
18559
- */
18560
- getToolFunctions() {
18561
- return {
18562
- async [SPAWN_AGENT_TOOL_NAME](args) {
18563
- return spawnAgentViaBrowser(args);
18564
- },
18565
- };
18566
- }
18567
- }
18568
- // Note: [💞] Ignore a discrepancy between file name and entity name
18569
-
18570
- /**
18571
- * Creates system-message instructions for `USE TIMEOUT`.
18572
- *
18573
- * @private internal utility of USE TIMEOUT
18574
- */
18575
- function createTimeoutSystemMessage(extraInstructions) {
18576
- return spacetrim.spaceTrim((block) => `
18577
- ## Timeout scheduling
18578
-
18579
- - Use \`set_timeout\` to wake this same chat thread in the future.
18580
- - Use \`list_timeouts\` to review timeout ids/details across all chats for the same user+agent scope.
18581
- - \`cancel_timeout\` accepts either one timeout id or \`allActive: true\` to cancel all active timeouts in this same user+agent scope.
18582
- - Use \`update_timeout\` to pause/resume, edit next run, edit recurrence, or update timeout payload details.
18583
- - When one timeout elapses, you will receive a new user-like message that explicitly says it is a timeout wake-up and includes the \`timeoutId\`.
18584
- - Do not claim a timer was set or cancelled unless the tool confirms it.
18585
- ${block(extraInstructions)}
18586
- `);
18587
- }
18588
-
18589
- /**
18590
- * Marker property stored inside serialized tool-execution envelopes.
18591
- *
18592
- * @private internal tool-execution transport
18593
- */
18594
- const TOOL_EXECUTION_ENVELOPE_MARKER = '__promptbookToolExecutionEnvelope';
18595
- /**
18596
- * Creates one serialized tool-execution envelope.
18597
- *
18598
- * @private internal tool-execution transport
18599
- */
18600
- function createToolExecutionEnvelope(options) {
18601
- const envelope = {
18602
- [TOOL_EXECUTION_ENVELOPE_MARKER]: true,
18603
- assistantMessage: options.assistantMessage,
18604
- toolResult: options.toolResult,
18605
- };
18606
- return JSON.stringify(envelope);
18607
- }
18608
- /**
18609
- * Parses one serialized tool-execution envelope when present.
18610
- *
18611
- * @private internal tool-execution transport
18612
- */
18613
- function parseToolExecutionEnvelope(rawValue) {
18614
- if (typeof rawValue !== 'string') {
18615
- return null;
18616
- }
18617
- try {
18618
- const parsedValue = JSON.parse(rawValue);
18619
- if (!parsedValue ||
18620
- typeof parsedValue !== 'object' ||
18621
- parsedValue[TOOL_EXECUTION_ENVELOPE_MARKER] !== true ||
18622
- typeof parsedValue.assistantMessage !== 'string') {
18623
- return null;
18624
- }
18625
- return {
18626
- assistantMessage: parsedValue.assistantMessage,
18627
- toolResult: parsedValue.toolResult,
18628
- };
18629
- }
18630
- catch (_a) {
18631
- return null;
18632
- }
18633
- }
18634
- // Note: [💞] Ignore a discrepancy between file name and entity name
18635
-
18636
- /**
18637
- * Builds a disabled timeout-tool payload.
18638
- *
18639
- * @private internal utility of USE TIMEOUT
18640
- */
18641
- function createDisabledTimeoutResult(action, message) {
18642
- return {
18643
- action,
18644
- status: 'disabled',
18645
- message,
18646
- };
18647
- }
18648
- /**
18649
- * Resolves the runtime adapter for timeout tools or returns disabled payload when unavailable.
18650
- *
18651
- * @private internal utility of USE TIMEOUT
18652
- */
18653
- function getTimeoutToolRuntimeAdapterOrDisabledResult(action, runtimeContext) {
18654
- if (!runtimeContext.enabled || !runtimeContext.chatId) {
18655
- return {
18656
- adapter: null,
18657
- disabledResult: createDisabledTimeoutResult(action, 'Timeouts are unavailable because this conversation is not running inside a chat thread.'),
18658
- };
18659
- }
18660
- {
18661
- return {
18662
- adapter: null,
18663
- disabledResult: createDisabledTimeoutResult(action, 'Timeout runtime is not available in this environment.'),
18664
- };
18665
- }
18666
- }
18667
-
18668
- /**
18669
- * Generates random token
18670
- *
18671
- * Note: `$` is used to indicate that this function is not a pure function - it is not deterministic
18672
- * Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
18673
- *
18674
- * @returns secure random token
18675
- *
18676
- * @private internal helper function
18677
- */
18678
- function $randomToken(randomness) {
18679
- return CryptoJS__default["default"].lib.WordArray.random(randomness).toString(CryptoJS__default["default"].enc.Hex);
18680
- }
18681
- // TODO: [🤶] Maybe export through `@promptbook/utils` or `@promptbook/random` package
18682
- // TODO: Maybe use nanoid instead https://github.com/ai/nanoid
18683
-
18684
- /**
18685
- * This error indicates errors during the execution of the pipeline
18686
- *
18687
- * @public exported from `@promptbook/core`
18688
- */
18689
- class PipelineExecutionError extends Error {
18690
- constructor(message) {
18691
- // Added id parameter
18692
- super(message);
18693
- this.name = 'PipelineExecutionError';
18694
- // TODO: [🐙] DRY - Maybe $randomId
18695
- this.id = `error-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid similar char conflicts */)}`;
18696
- Object.setPrototypeOf(this, PipelineExecutionError.prototype);
18697
- }
18698
- }
18699
- // TODO: [🧠][🌂] Add id to all errors
18700
-
18701
- /**
18702
- * Default number of rows returned by `list_timeouts`.
18703
- *
18704
- * @private internal USE TIMEOUT constant
18705
- */
18706
- const DEFAULT_LIST_TIMEOUTS_LIMIT = 20;
18707
- /**
18708
- * Hard cap for `list_timeouts` page size.
18709
- *
18710
- * @private internal USE TIMEOUT constant
18711
- */
18712
- const MAX_LIST_TIMEOUTS_LIMIT = 100;
18713
- /**
18714
- * Creates one formatted timeout-argument validation error.
18715
- *
18716
- * @private internal utility of USE TIMEOUT
18717
- */
18718
- function createTimeoutToolArgsError(message) {
18719
- return new PipelineExecutionError(spacetrim.spaceTrim(`
18720
- ${message}
18721
- `));
18722
- }
18723
- /**
18724
- * Normalizes one optional timeout id string.
18725
- *
18726
- * @private internal utility of USE TIMEOUT
18727
- */
18728
- function normalizeOptionalTimeoutId(value) {
18729
- return typeof value === 'string' ? value.trim() : '';
18730
- }
18731
- /**
18732
- * Parses timeout target selection for tools that accept either `timeoutId` or `allActive: true`.
18733
- *
18734
- * @private internal utility of USE TIMEOUT
18735
- */
18736
- function parseTimeoutTargetSelection(args, options) {
18737
- const timeoutId = normalizeOptionalTimeoutId(args.timeoutId);
18738
- const allActive = args.allActive === true;
18739
- if (timeoutId && allActive) {
18740
- throw createTimeoutToolArgsError(options.bothMessage);
18741
- }
18742
- if (allActive) {
18743
- return { allActive: true };
18744
- }
18745
- if (!timeoutId) {
18746
- throw createTimeoutToolArgsError(options.missingMessage);
18747
- }
18748
- return {
18749
- timeoutId,
18750
- allActive: false,
18751
- };
18752
- }
18753
- /**
18754
- * Parses one explicit `dueAt` update value.
18755
- *
18756
- * @private internal utility of USE TIMEOUT
18757
- */
18758
- function parseOptionalTimeoutDueAt(value) {
18759
- if (typeof value !== 'string' || value.trim().length === 0) {
18760
- return undefined;
18761
- }
18762
- const normalizedDueAt = value.trim();
18763
- const dueAtTimestamp = Date.parse(normalizedDueAt);
18764
- if (!Number.isFinite(dueAtTimestamp)) {
18765
- throw createTimeoutToolArgsError('Timeout `dueAt` must be one valid ISO timestamp.');
18766
- }
18767
- return new Date(dueAtTimestamp).toISOString();
18768
- }
18769
- /**
18770
- * Parses one explicit `extendByMs` update value.
18771
- *
18772
- * @private internal utility of USE TIMEOUT
18773
- */
18774
- function parseOptionalTimeoutExtendByMs(value) {
18775
- if (typeof value !== 'number') {
18776
- return undefined;
18777
- }
18778
- if (!Number.isFinite(value) || value <= 0) {
18779
- throw createTimeoutToolArgsError('Timeout `extendByMs` must be a positive number of milliseconds.');
18780
- }
18781
- return Math.floor(value);
18782
- }
18783
- /**
18784
- * Parses one explicit `recurrenceIntervalMs` update value.
18785
- *
18786
- * @private internal utility of USE TIMEOUT
18787
- */
18788
- function parseOptionalTimeoutRecurrenceInterval(value) {
18789
- if (value === null) {
18790
- return null;
18791
- }
18792
- if (typeof value !== 'number') {
18793
- return undefined;
18794
- }
18795
- if (!Number.isFinite(value) || value <= 0) {
18796
- throw createTimeoutToolArgsError('Timeout `recurrenceIntervalMs` must be a positive number of milliseconds or `null`.');
18797
- }
18798
- return Math.floor(value);
18799
- }
18800
- /**
18801
- * Parses one explicit `message` update value.
18802
- *
18803
- * @private internal utility of USE TIMEOUT
18804
- */
18805
- function parseOptionalTimeoutMessage(value) {
18806
- if (value === null) {
18807
- return null;
18808
- }
18809
- if (typeof value !== 'string') {
18810
- return undefined;
18811
- }
18812
- const normalizedMessage = value.trim();
18813
- return normalizedMessage.length > 0 ? normalizedMessage : null;
18814
- }
18815
- /**
18816
- * Parses one explicit `parameters` update value.
18817
- *
18818
- * @private internal utility of USE TIMEOUT
18819
- */
18820
- function parseOptionalTimeoutParameters(value) {
18821
- if (value === undefined) {
18822
- return undefined;
18823
- }
18824
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
18825
- throw createTimeoutToolArgsError('Timeout `parameters` must be one JSON object.');
18826
- }
18827
- return value;
18828
- }
18829
- /**
18830
- * Parses one explicit `paused` update value.
18831
- *
18832
- * @private internal utility of USE TIMEOUT
18833
- */
18834
- function parseOptionalTimeoutPaused(value) {
18835
- return typeof value === 'boolean' ? value : undefined;
18836
- }
18837
- /**
18838
- * Parses patch fields for `update_timeout`.
18839
- *
18840
- * @private internal utility of USE TIMEOUT
18841
- */
18842
- function parseTimeoutUpdatePatch(args) {
18843
- const patch = {};
18844
- const dueAt = parseOptionalTimeoutDueAt(args.dueAt);
18845
- const extendByMs = parseOptionalTimeoutExtendByMs(args.extendByMs);
18846
- const recurrenceIntervalMs = parseOptionalTimeoutRecurrenceInterval(args.recurrenceIntervalMs);
18847
- const message = parseOptionalTimeoutMessage(args.message);
18848
- const parameters = parseOptionalTimeoutParameters(args.parameters);
18849
- const paused = parseOptionalTimeoutPaused(args.paused);
18850
- if (dueAt !== undefined) {
18851
- patch.dueAt = dueAt;
18852
- }
18853
- if (extendByMs !== undefined) {
18854
- patch.extendByMs = extendByMs;
18855
- }
18856
- if (patch.dueAt !== undefined && patch.extendByMs !== undefined) {
18857
- throw createTimeoutToolArgsError('Timeout update cannot include both `dueAt` and `extendByMs`.');
18858
- }
18859
- if (recurrenceIntervalMs !== undefined) {
18860
- patch.recurrenceIntervalMs = recurrenceIntervalMs;
18861
- }
18862
- if (message !== undefined) {
18863
- patch.message = message;
18864
- }
18865
- if (parameters !== undefined) {
18866
- patch.parameters = parameters;
18867
- }
18868
- if (paused !== undefined) {
18869
- patch.paused = paused;
18870
- }
18871
- return patch;
18872
- }
18873
- /**
18874
- * Determines whether the patch contains fields that are only supported for single-timeout updates.
18875
- *
18876
- * @private internal utility of USE TIMEOUT
18877
- */
18878
- function hasSingleTimeoutOnlyPatchFields(patch) {
18879
- return (patch.dueAt !== undefined ||
18880
- patch.extendByMs !== undefined ||
18881
- patch.recurrenceIntervalMs !== undefined ||
18882
- patch.message !== undefined ||
18883
- patch.parameters !== undefined);
18884
- }
18885
- /**
18886
- * Parses bulk timeout update arguments.
18887
- *
18888
- * @private internal utility of USE TIMEOUT
18889
- */
18890
- function parseBulkTimeoutUpdateArgs(patch) {
18891
- if (patch.paused === undefined) {
18892
- throw createTimeoutToolArgsError('Bulk timeout update with `allActive: true` requires `paused` to be explicitly set.');
18893
- }
18894
- if (hasSingleTimeoutOnlyPatchFields(patch)) {
18895
- throw createTimeoutToolArgsError('Bulk timeout update only supports the `paused` field.');
18896
- }
18897
- return {
18898
- allActive: true,
18899
- paused: patch.paused,
18900
- };
18901
- }
18902
- /**
18903
- * Parses single-timeout update arguments.
18904
- *
18905
- * @private internal utility of USE TIMEOUT
18906
- */
18907
- function parseSingleTimeoutUpdateArgs(timeoutId, patch) {
18908
- if (!timeoutId) {
18909
- throw createTimeoutToolArgsError('Timeout `timeoutId` is required for single-timeout updates.');
18910
- }
18911
- if (Object.keys(patch).length === 0) {
18912
- throw createTimeoutToolArgsError('Timeout update must include at least one editable field.');
18913
- }
18914
- return {
18915
- timeoutId,
18916
- patch,
18917
- };
18918
- }
18919
- /**
18920
- * Parses and validates `USE TIMEOUT` tool arguments.
18921
- *
18922
- * @private internal utility of USE TIMEOUT
18923
- */
18924
- const parseTimeoutToolArgs = {
18925
- /**
18926
- * Parses `set_timeout` input.
18927
- */
18928
- set(args) {
18929
- const parsedMilliseconds = Number(args.milliseconds);
18930
- if (!Number.isFinite(parsedMilliseconds) || parsedMilliseconds <= 0) {
18931
- throw new PipelineExecutionError(spacetrim.spaceTrim(`
18932
- Timeout \`milliseconds\` must be a positive number.
18933
- `));
18934
- }
18935
- const message = typeof args.message === 'string' ? args.message.trim() : '';
18936
- return {
18937
- milliseconds: Math.floor(parsedMilliseconds),
18938
- ...(message ? { message } : {}),
18939
- };
18940
- },
18941
- /**
18942
- * Parses `cancel_timeout` input.
18943
- */
18944
- cancel(args) {
18945
- const target = parseTimeoutTargetSelection(args, {
18946
- bothMessage: 'Timeout cancellation must target either one `timeoutId` or `allActive: true`, not both.',
18947
- missingMessage: 'Timeout `timeoutId` is required unless you pass `allActive: true`.',
18948
- });
18949
- if (target.allActive) {
18950
- return { allActive: true };
18951
- }
18952
- return { timeoutId: target.timeoutId };
18953
- },
18954
- /**
18955
- * Parses `list_timeouts` input.
18956
- */
18957
- list(args) {
18958
- if (args.includeFinished !== undefined && typeof args.includeFinished !== 'boolean') {
18959
- throw new PipelineExecutionError(spacetrim.spaceTrim(`
18960
- Timeout \`includeFinished\` must be a boolean when provided.
18961
- `));
18962
- }
18963
- const parsedLimit = args.limit === undefined ? DEFAULT_LIST_TIMEOUTS_LIMIT : Math.floor(Number(args.limit));
18964
- if (!Number.isFinite(parsedLimit) || parsedLimit <= 0) {
18965
- throw new PipelineExecutionError(spacetrim.spaceTrim(`
18966
- Timeout \`limit\` must be a positive number.
18967
- `));
18968
- }
18969
- if (parsedLimit > MAX_LIST_TIMEOUTS_LIMIT) {
18970
- throw new PipelineExecutionError(spacetrim.spaceTrim(`
18971
- Timeout \`limit\` must be at most \`${MAX_LIST_TIMEOUTS_LIMIT}\`.
18972
- `));
18973
- }
18974
- return {
18975
- includeFinished: args.includeFinished === true,
18976
- limit: parsedLimit,
18977
- };
18978
- },
18979
- /**
18980
- * Parses `update_timeout` input.
18981
- */
18982
- update(args) {
18983
- const target = parseTimeoutTargetSelection(args, {
18984
- bothMessage: 'Timeout update must target either one `timeoutId` or `allActive: true`, not both.',
18985
- missingMessage: 'Timeout update requires one `timeoutId` or `allActive: true`.',
18986
- });
18987
- const patch = parseTimeoutUpdatePatch(args);
18988
- return target.allActive
18989
- ? parseBulkTimeoutUpdateArgs(patch)
18990
- : parseSingleTimeoutUpdateArgs(target.timeoutId, patch);
18991
- },
18992
- };
18993
-
18994
- /**
18995
- * Resolves timeout runtime context from hidden tool arguments.
18996
- *
18997
- * @private internal utility of USE TIMEOUT
18998
- */
18999
- function resolveTimeoutRuntimeContext(args) {
19000
- const runtimeContext = readToolRuntimeContextFromToolArgs(args);
19001
- const chatContext = runtimeContext === null || runtimeContext === void 0 ? void 0 : runtimeContext.chat;
19002
- return {
19003
- enabled: Boolean(chatContext === null || chatContext === void 0 ? void 0 : chatContext.chatId),
19004
- chatId: chatContext === null || chatContext === void 0 ? void 0 : chatContext.chatId,
19005
- userId: chatContext === null || chatContext === void 0 ? void 0 : chatContext.userId,
19006
- agentId: chatContext === null || chatContext === void 0 ? void 0 : chatContext.agentId,
19007
- agentName: chatContext === null || chatContext === void 0 ? void 0 : chatContext.agentName,
19008
- promptParameters: normalizePromptParameters(chatContext === null || chatContext === void 0 ? void 0 : chatContext.parameters),
19009
- };
19010
- }
19011
- /**
19012
- * Normalizes stored prompt parameters carried by timeout runtime context.
19013
- *
19014
- * @private internal utility of USE TIMEOUT
19015
- */
19016
- function normalizePromptParameters(rawParameters) {
19017
- if (!rawParameters || typeof rawParameters !== 'object' || Array.isArray(rawParameters)) {
19018
- return {};
19019
- }
19020
- const normalizedEntries = Object.entries(rawParameters).filter(([, value]) => typeof value === 'string');
19021
- return Object.fromEntries(normalizedEntries);
19022
- }
19023
-
19024
- /**
19025
- * Tool names provided by the `USE TIMEOUT` commitment.
19026
- *
19027
- * @private internal USE TIMEOUT constant
19028
- */
19029
- const TimeoutToolNames = {
19030
- set: 'set_timeout',
19031
- cancel: 'cancel_timeout',
19032
- list: 'list_timeouts',
19033
- update: 'update_timeout',
19034
- };
19035
-
19036
- /**
19037
- * Maximum number of timeout rows rendered into the assistant-visible `list_timeouts` message.
19038
- *
19039
- * @private internal USE TIMEOUT constant
19040
- */
19041
- const MAX_ASSISTANT_VISIBLE_TIMEOUT_ROWS = 20;
19042
- /**
19043
- * Maximum number of timeout ids rendered in bulk-action summaries.
19044
- *
19045
- * @private internal USE TIMEOUT constant
19046
- */
19047
- const MAX_ASSISTANT_VISIBLE_BULK_TIMEOUT_IDS = 10;
19048
- /**
19049
- * Gets `USE TIMEOUT` tool function implementations.
19050
- *
19051
- * @private internal utility of USE TIMEOUT
19052
- */
19053
- function createTimeoutToolFunctions() {
19054
- return {
19055
- async [TimeoutToolNames.set](args) {
19056
- const runtimeContext = resolveTimeoutRuntimeContext(args);
19057
- const { adapter, disabledResult } = getTimeoutToolRuntimeAdapterOrDisabledResult('set', runtimeContext);
19058
- if (!adapter || disabledResult) {
19059
- return JSON.stringify(disabledResult);
19060
- }
19061
- try {
19062
- const parsedArgs = parseTimeoutToolArgs.set(args);
19063
- const scheduledTimeout = await adapter.scheduleTimeout(parsedArgs, runtimeContext);
19064
- const result = {
19065
- action: 'set',
19066
- status: 'set',
19067
- timeoutId: scheduledTimeout.timeoutId,
19068
- dueAt: scheduledTimeout.dueAt,
19069
- };
19070
- return createToolExecutionEnvelope({
19071
- assistantMessage: 'The timer was set.',
19072
- toolResult: result,
19073
- });
19074
- }
19075
- catch (error) {
19076
- const result = {
19077
- action: 'set',
19078
- status: 'error',
19079
- message: error instanceof Error ? error.message : String(error),
19080
- };
19081
- return JSON.stringify(result);
19082
- }
19083
- },
19084
- async [TimeoutToolNames.cancel](args) {
19085
- const runtimeContext = resolveTimeoutRuntimeContext(args);
19086
- const { adapter, disabledResult } = getTimeoutToolRuntimeAdapterOrDisabledResult('cancel', runtimeContext);
19087
- if (!adapter || disabledResult) {
19088
- return JSON.stringify(disabledResult);
19089
- }
19090
- try {
19091
- const parsedArgs = parseTimeoutToolArgs.cancel(args);
19092
- const cancelledTimeout = await adapter.cancelTimeout(parsedArgs, runtimeContext);
19093
- if (cancelledTimeout.status === 'cancelled_all') {
19094
- const result = {
19095
- action: 'cancel',
19096
- status: 'cancelled_all',
19097
- cancelledCount: cancelledTimeout.cancelledCount || 0,
19098
- cancelledTimeoutIds: cancelledTimeout.cancelledTimeoutIds || [],
19099
- hasMore: cancelledTimeout.hasMore,
19100
- };
19101
- return createToolExecutionEnvelope({
19102
- assistantMessage: createBulkCancelAssistantMessage({
19103
- cancelledCount: result.cancelledCount || 0,
19104
- cancelledTimeoutIds: result.cancelledTimeoutIds || [],
19105
- hasMore: result.hasMore,
19106
- }),
19107
- toolResult: result,
19108
- });
19109
- }
19110
- const result = {
19111
- action: 'cancel',
19112
- status: cancelledTimeout.status,
19113
- timeoutId: cancelledTimeout.timeoutId,
19114
- dueAt: cancelledTimeout.dueAt,
19115
- };
19116
- return createToolExecutionEnvelope({
19117
- assistantMessage: cancelledTimeout.status === 'cancelled'
19118
- ? 'The timer was cancelled.'
19119
- : 'The timer was already inactive.',
19120
- toolResult: result,
19121
- });
19122
- }
19123
- catch (error) {
19124
- const result = {
19125
- action: 'cancel',
19126
- status: 'error',
19127
- message: error instanceof Error ? error.message : String(error),
19128
- };
19129
- return JSON.stringify(result);
19130
- }
19131
- },
19132
- async [TimeoutToolNames.list](args) {
19133
- const runtimeContext = resolveTimeoutRuntimeContext(args);
19134
- const { adapter, disabledResult } = getTimeoutToolRuntimeAdapterOrDisabledResult('list', runtimeContext);
19135
- if (!adapter || disabledResult) {
19136
- return JSON.stringify(disabledResult);
19137
- }
19138
- try {
19139
- const parsedArgs = parseTimeoutToolArgs.list(args);
19140
- const listedTimeouts = await adapter.listTimeouts(parsedArgs, runtimeContext);
19141
- const result = {
19142
- action: 'list',
19143
- status: 'listed',
19144
- items: listedTimeouts.items,
19145
- total: listedTimeouts.total,
19146
- };
19147
- return createToolExecutionEnvelope({
19148
- assistantMessage: createListedTimeoutsAssistantMessage({
19149
- total: listedTimeouts.total,
19150
- items: listedTimeouts.items,
19151
- }),
19152
- toolResult: result,
19153
- });
19154
- }
19155
- catch (error) {
19156
- const result = {
19157
- action: 'list',
19158
- status: 'error',
19159
- message: error instanceof Error ? error.message : String(error),
19160
- };
19161
- return JSON.stringify(result);
19162
- }
19163
- },
19164
- async [TimeoutToolNames.update](args) {
19165
- const runtimeContext = resolveTimeoutRuntimeContext(args);
19166
- const { adapter, disabledResult } = getTimeoutToolRuntimeAdapterOrDisabledResult('update', runtimeContext);
19167
- if (!adapter || disabledResult) {
19168
- return JSON.stringify(disabledResult);
19169
- }
19170
- try {
19171
- const parsedArgs = parseTimeoutToolArgs.update(args);
19172
- const updatedTimeout = await adapter.updateTimeout(parsedArgs, runtimeContext);
19173
- if (updatedTimeout.status === 'updated_all') {
19174
- const result = {
19175
- action: 'update',
19176
- status: 'updated_all',
19177
- updatedCount: updatedTimeout.updatedCount,
19178
- matchedCount: updatedTimeout.matchedCount,
19179
- updatedTimeoutIds: updatedTimeout.updatedTimeoutIds,
19180
- hasMore: updatedTimeout.hasMore,
19181
- };
19182
- return createToolExecutionEnvelope({
19183
- assistantMessage: createBulkUpdateAssistantMessage({
19184
- paused: 'allActive' in parsedArgs && parsedArgs.allActive ? parsedArgs.paused : false,
19185
- updatedCount: updatedTimeout.updatedCount,
19186
- matchedCount: updatedTimeout.matchedCount,
19187
- updatedTimeoutIds: updatedTimeout.updatedTimeoutIds,
19188
- hasMore: updatedTimeout.hasMore,
19189
- }),
19190
- toolResult: result,
19191
- });
19192
- }
19193
- if (updatedTimeout.status === 'not_found') {
19194
- const result = {
19195
- action: 'update',
19196
- status: 'not_found',
19197
- timeoutId: updatedTimeout.timeoutId,
19198
- };
19199
- return createToolExecutionEnvelope({
19200
- assistantMessage: 'The timeout was not found.',
19201
- toolResult: result,
19202
- });
19203
- }
19204
- if (updatedTimeout.status === 'conflict') {
19205
- const conflictMessage = updatedTimeout.reason === 'running'
19206
- ? 'Running timeout cannot be edited.'
19207
- : 'Finished timeout cannot be edited.';
19208
- const result = {
19209
- action: 'update',
19210
- status: 'conflict',
19211
- timeoutId: updatedTimeout.timeoutId,
19212
- message: conflictMessage,
19213
- };
19214
- return createToolExecutionEnvelope({
19215
- assistantMessage: conflictMessage,
19216
- toolResult: result,
19217
- });
19218
- }
19219
- const result = {
19220
- action: 'update',
19221
- status: 'updated',
19222
- timeoutId: updatedTimeout.timeout.timeoutId,
19223
- dueAt: updatedTimeout.timeout.dueAt,
19224
- paused: updatedTimeout.timeout.paused,
19225
- recurrenceIntervalMs: updatedTimeout.timeout.recurrenceIntervalMs,
19226
- };
19227
- return createToolExecutionEnvelope({
19228
- assistantMessage: `Updated timeout ${JSON.stringify(updatedTimeout.timeout.timeoutId)}.`,
19229
- toolResult: result,
19230
- });
19231
- }
19232
- catch (error) {
19233
- const result = {
19234
- action: 'update',
19235
- status: 'error',
19236
- message: error instanceof Error ? error.message : String(error),
19237
- };
19238
- return JSON.stringify(result);
19239
- }
19240
- },
19241
- };
19242
- }
19243
- /**
19244
- * Creates assistant-visible summary for one `list_timeouts` response.
19245
- *
19246
- * @private internal utility of USE TIMEOUT
19247
- */
19248
- function createListedTimeoutsAssistantMessage(options) {
19249
- if (options.total <= 0 || options.items.length === 0) {
19250
- return 'Found 0 timeouts.';
19251
- }
19252
- const visibleItems = options.items.slice(0, MAX_ASSISTANT_VISIBLE_TIMEOUT_ROWS);
19253
- const summaryRows = visibleItems.map((item, index) => `${index + 1}. ${formatTimeoutListRow(item)}`);
19254
- const hiddenCount = Math.max(0, options.total - visibleItems.length);
19255
- if (hiddenCount > 0) {
19256
- summaryRows.push(`...and ${hiddenCount} more.`);
19257
- }
19258
- return spacetrim.spaceTrim((block) => `
19259
- Found ${options.total} ${options.total === 1 ? 'timeout' : 'timeouts'}:
19260
- ${block(summaryRows.join('\n'))}
19261
- `);
19262
- }
19263
- /**
19264
- * Formats one timeout row for assistant-visible timeout listings.
19265
- *
19266
- * @private internal utility of USE TIMEOUT
19267
- */
19268
- function formatTimeoutListRow(item) {
19269
- const normalizedMessage = typeof item.message === 'string' ? item.message.trim() : '';
19270
- const messageSuffix = normalizedMessage ? ` | message ${JSON.stringify(normalizedMessage)}` : '';
19271
- const recurrenceSuffix = typeof item.recurrenceIntervalMs === 'number' && item.recurrenceIntervalMs > 0
19272
- ? ` | recurrence ${item.recurrenceIntervalMs}ms`
19273
- : '';
19274
- const pausedSuffix = item.paused ? ' (paused)' : '';
19275
- return `${item.timeoutId} | ${item.status}${pausedSuffix} | chat ${item.chatId} | due ${item.dueAt}${recurrenceSuffix}${messageSuffix}`;
19276
- }
19277
- /**
19278
- * Creates assistant-visible summary for bulk timeout cancellation.
19279
- *
19280
- * @private internal utility of USE TIMEOUT
19281
- */
19282
- function createBulkCancelAssistantMessage(options) {
19283
- if (options.cancelledCount <= 0) {
19284
- return 'No active timeouts were found to cancel.';
19285
- }
19286
- const visibleTimeoutIds = options.cancelledTimeoutIds.slice(0, MAX_ASSISTANT_VISIBLE_BULK_TIMEOUT_IDS);
19287
- const hiddenIdsCount = Math.max(0, options.cancelledTimeoutIds.length - visibleTimeoutIds.length);
19288
- const hasMoreSuffix = options.hasMore ? ' Additional active timeouts may still exist.' : '';
19289
- const idsSuffix = visibleTimeoutIds.length > 0
19290
- ? ` Cancelled ids: ${visibleTimeoutIds.join(', ')}${hiddenIdsCount > 0 ? `, and ${hiddenIdsCount} more.` : '.'}`
19291
- : '';
19292
- return `Cancelled ${options.cancelledCount} active ${options.cancelledCount === 1 ? 'timeout' : 'timeouts'}.${idsSuffix}${hasMoreSuffix}`;
19293
- }
19294
- /**
19295
- * Creates assistant-visible summary for bulk timeout pause/resume updates.
19296
- *
19297
- * @private internal utility of USE TIMEOUT
19298
- */
19299
- function createBulkUpdateAssistantMessage(options) {
19300
- if (options.matchedCount <= 0) {
19301
- return options.paused
19302
- ? 'No active queued timeouts were found to pause.'
19303
- : 'No paused queued timeouts were found to resume.';
19304
- }
19305
- const verb = options.paused ? 'Paused' : 'Resumed';
19306
- const visibleTimeoutIds = options.updatedTimeoutIds.slice(0, MAX_ASSISTANT_VISIBLE_BULK_TIMEOUT_IDS);
19307
- const hiddenIdsCount = Math.max(0, options.updatedTimeoutIds.length - visibleTimeoutIds.length);
19308
- const skippedCount = Math.max(0, options.matchedCount - options.updatedCount);
19309
- const idsSuffix = visibleTimeoutIds.length > 0
19310
- ? ` Updated ids: ${visibleTimeoutIds.join(', ')}${hiddenIdsCount > 0 ? `, and ${hiddenIdsCount} more.` : '.'}`
19311
- : '';
19312
- const skippedSuffix = skippedCount > 0 ? ` Skipped ${skippedCount} due to concurrent changes.` : '';
19313
- const hasMoreSuffix = options.hasMore ? ' Additional matching timeouts may still exist.' : '';
19314
- return `${verb} ${options.updatedCount} ${options.updatedCount === 1 ? 'timeout' : 'timeouts'}.${idsSuffix}${skippedSuffix}${hasMoreSuffix}`;
19315
- }
19316
-
19317
- /**
19318
- * Adds `USE TIMEOUT` tool definitions while preserving already registered tools.
19319
- *
19320
- * @private internal utility of USE TIMEOUT
19321
- */
19322
- function createTimeoutTools(existingTools = []) {
19323
- const tools = [...existingTools];
19324
- if (!tools.some((tool) => tool.name === TimeoutToolNames.set)) {
19325
- tools.push({
19326
- name: TimeoutToolNames.set,
19327
- description: 'Schedule one thread-scoped wake-up in the current chat. The timer returns immediately and wakes this same conversation later.',
19328
- parameters: {
19329
- type: 'object',
19330
- properties: {
19331
- milliseconds: {
19332
- type: 'number',
19333
- description: 'Delay in milliseconds before the timeout wakes the same chat thread.',
19334
- },
19335
- message: {
19336
- type: 'string',
19337
- description: 'Optional note appended to the future timeout wake-up message.',
19338
- },
19339
- },
19340
- required: ['milliseconds'],
19341
- },
19342
- });
19343
- }
19344
- if (!tools.some((tool) => tool.name === TimeoutToolNames.cancel)) {
19345
- tools.push({
19346
- name: TimeoutToolNames.cancel,
19347
- description: 'Cancel one timeout by id or cancel all active timeouts across chats for the same user+agent scope.',
19348
- parameters: {
19349
- type: 'object',
19350
- properties: {
19351
- timeoutId: {
19352
- type: 'string',
19353
- description: 'Identifier returned earlier by `set_timeout` or `list_timeouts`.',
19354
- },
19355
- allActive: {
19356
- type: 'boolean',
19357
- description: 'When true, cancel all currently active timeouts across chats in this user+agent scope.',
19358
- },
19359
- },
19360
- },
19361
- });
19362
- }
19363
- if (!tools.some((tool) => tool.name === TimeoutToolNames.list)) {
19364
- tools.push({
19365
- name: TimeoutToolNames.list,
19366
- description: 'List timeout details across all chats for this same user+agent scope so they can be reviewed and managed.',
19367
- parameters: {
19368
- type: 'object',
19369
- properties: {
19370
- includeFinished: {
19371
- type: 'boolean',
19372
- description: 'When true, include completed, failed, and cancelled rows in addition to active timeouts.',
19373
- },
19374
- limit: {
19375
- type: 'number',
19376
- description: 'Maximum number of rows to return (default 20, max 100).',
19377
- },
19378
- },
19379
- },
19380
- });
19381
- }
19382
- if (!tools.some((tool) => tool.name === TimeoutToolNames.update)) {
19383
- tools.push({
19384
- name: TimeoutToolNames.update,
19385
- description: 'Update one timeout (pause/resume, next run, recurrence, payload) or pause/resume all active queued timeouts across chats.',
19386
- parameters: {
19387
- type: 'object',
19388
- properties: {
19389
- timeoutId: {
19390
- type: 'string',
19391
- description: 'Identifier returned earlier by `set_timeout` or `list_timeouts` for one timeout update.',
19392
- },
19393
- allActive: {
19394
- type: 'boolean',
19395
- description: 'When true, run one bulk pause/resume across all active queued timeouts in this same user+agent scope.',
19396
- },
19397
- paused: {
19398
- type: 'boolean',
19399
- description: 'Pause (`true`) or resume (`false`) one timeout; with `allActive: true` this pauses/resumes all active queued timeouts.',
19400
- },
19401
- dueAt: {
19402
- type: 'string',
19403
- description: 'Set the next run timestamp (ISO string). Cannot be used with `extendByMs`.',
19404
- },
19405
- extendByMs: {
19406
- type: 'number',
19407
- description: 'Move next run by this many milliseconds. Cannot be used with `dueAt`.',
19408
- },
19409
- recurrenceIntervalMs: {
19410
- type: 'number',
19411
- description: 'Set recurrence interval in milliseconds; pass `null` to disable recurrence.',
19412
- },
19413
- message: {
19414
- type: 'string',
19415
- description: 'Set wake-up message text for this timeout; pass empty string to clear.',
19416
- },
19417
- parameters: {
19418
- type: 'object',
19419
- description: 'Replace stored JSON parameters passed back when timeout fires.',
19420
- },
19421
- },
19422
- },
19423
- });
19424
- }
19425
- return tools;
19426
- }
19427
-
19428
- /**
19429
- * `USE TIMEOUT` commitment definition.
19430
- *
19431
- * The `USE TIMEOUT` commitment enables timeout wake-ups and scoped timeout management.
19432
- *
19433
- * @private [🪔] Maybe export the commitments through some package
19434
- */
19435
- class UseTimeoutCommitmentDefinition extends BaseCommitmentDefinition {
19436
- constructor() {
19437
- super('USE TIMEOUT');
19438
- }
19439
- get requiresContent() {
19440
- return false;
19441
- }
19442
- /**
19443
- * Short one-line description of `USE TIMEOUT`.
19444
- */
19445
- get description() {
19446
- return 'Enable timeout wake-ups plus scoped timeout listing, updates, and cancellation across chats.';
19447
- }
19448
- /**
19449
- * Icon for this commitment.
19450
- */
19451
- get icon() {
19452
- return '⏱️';
19453
- }
19454
- /**
19455
- * Markdown documentation for `USE TIMEOUT`.
19456
- */
19457
- get documentation() {
19458
- return spacetrim.spaceTrim(`
19459
- # USE TIMEOUT
19460
-
19461
- Enables timeout wake-ups and timeout management for the same user+agent scope.
19462
-
19463
- ## Key aspects
19464
-
19465
- - The agent uses \`set_timeout\` to schedule a future wake-up in the same chat thread.
19466
- - The tool returns immediately while the timeout is stored and executed by the runtime later.
19467
- - The wake-up arrives as a new user-like timeout message in the same conversation.
19468
- - The agent can inspect known timeout details via \`list_timeouts\`.
19469
- - The agent can cancel one timeout by \`timeoutId\` or cancel all active timeouts via \`cancel_timeout\`.
19470
- - The agent can pause/resume and edit timeout details via \`update_timeout\`.
19471
- - Commitment content is treated as optional timeout policy instructions.
19472
-
19473
- ## Examples
19474
-
19475
- \`\`\`book
19476
- Follow-up Agent
19477
- USE TIMEOUT Remind yourself only when follow-up work is explicitly requested.
19478
- \`\`\`
19479
- `);
19480
- }
19481
- applyToAgentModelRequirements(requirements, content) {
19482
- const extraInstructions = formatOptionalInstructionBlock('Timeout instructions', content);
19483
- return this.appendToSystemMessage({
19484
- ...requirements,
19485
- tools: createTimeoutTools(requirements.tools || []),
19486
- _metadata: {
19487
- ...requirements._metadata,
19488
- useTimeout: content || true,
19489
- },
19490
- }, createTimeoutSystemMessage(extraInstructions));
19491
- }
19492
- /**
19493
- * Gets human-readable titles for tool functions provided by this commitment.
19494
- */
19495
- getToolTitles() {
19496
- return {
19497
- [TimeoutToolNames.set]: 'Set timer',
19498
- [TimeoutToolNames.cancel]: 'Cancel timer',
19499
- [TimeoutToolNames.list]: 'List timers',
19500
- [TimeoutToolNames.update]: 'Update timer',
19501
- };
19502
- }
19503
- /**
19504
- * Gets `USE TIMEOUT` tool function implementations.
19505
- */
19506
- getToolFunctions() {
19507
- return createTimeoutToolFunctions();
19508
- }
19509
- }
19510
- // Note: [💞] Ignore a discrepancy between file name and entity name
19511
-
19512
- /**
19513
- * USE TIME commitment definition
19514
- *
19515
- * The `USE TIME` commitment indicates that the agent should be able to determine the current date and time.
19516
- *
19517
- * Example usage in agent source:
19518
- *
19519
- * ```book
19520
- * USE TIME
19521
- * USE TIME Prefer the user's local timezone.
19522
- * ```
19523
- *
19524
- * @private [🪔] Maybe export the commitments through some package
19525
- */
19526
- class UseTimeCommitmentDefinition extends BaseCommitmentDefinition {
19527
- constructor() {
19528
- super('USE TIME', ['CURRENT TIME', 'TIME', 'DATE']);
19529
- }
19530
- get requiresContent() {
19531
- return false;
19532
- }
19533
- /**
19534
- * Short one-line description of USE TIME.
19535
- */
19536
- get description() {
19537
- return 'Enable the agent to determine the current date and time.';
19538
- }
19539
- /**
19540
- * Icon for this commitment.
19541
- */
19542
- get icon() {
19543
- return '🕒';
19544
- }
19545
- /**
19546
- * Markdown documentation for USE TIME commitment.
19547
- */
19548
- get documentation() {
19549
- return spacetrim.spaceTrim(`
19550
- # USE TIME
19551
-
19552
- Enables the agent to determine the current date and time.
19553
-
19554
- ## Key aspects
19555
-
19556
- - This tool won't receive any input.
19557
- - It outputs the current date and time as an ISO 8601 string.
19558
- - Allows the agent to answer questions about the current time or date.
19559
- - The content following \`USE TIME\` is an arbitrary text that the agent should know (e.g. timezone preference).
19560
-
19561
- ## Examples
19562
-
19563
- \`\`\`book
19564
- Time-aware Assistant
19565
-
19566
- PERSONA You are a helpful assistant who knows the current time.
19567
- USE TIME
19568
- \`\`\`
19569
-
19570
- \`\`\`book
19571
- Travel Assistant
19572
-
19573
- PERSONA You help travelers with planning.
19574
- USE TIME Prefer the user's local timezone.
19575
- \`\`\`
19576
- `);
19577
- }
19578
- applyToAgentModelRequirements(requirements, content) {
19579
- // Get existing tools array or create new one
19580
- const existingTools = requirements.tools || [];
19581
- // Add 'get_current_time' to tools if not already present
19582
- const updatedTools = existingTools.some((tool) => tool.name === 'get_current_time')
19583
- ? existingTools
19584
- : [
19585
- ...existingTools,
19586
- {
19587
- name: 'get_current_time',
19588
- description: 'Get the current date and time in ISO 8601 format.',
19589
- parameters: {
19590
- type: 'object',
19591
- properties: {
19592
- timezone: {
19593
- type: 'string',
19594
- description: 'Optional timezone name (e.g. "Europe/Prague", "UTC", "America/New_York").',
19595
- },
19596
- },
19597
- required: [],
19598
- },
19599
- },
19600
- // <- TODO: !!!! define the function in LLM tools
19601
- ];
19602
- return appendAggregatedUseCommitmentPlaceholder({
19603
- ...requirements,
19604
- tools: updatedTools,
19605
- _metadata: {
19606
- ...requirements._metadata,
19607
- },
19608
- }, this.type);
19609
- }
19610
- /**
19611
- * Gets human-readable titles for tool functions provided by this commitment.
19612
- */
19613
- getToolTitles() {
19614
- return {
19615
- get_current_time: 'Get current time',
19616
- };
19617
- }
19618
- /**
19619
- * Gets the `get_current_time` tool function implementation.
19620
- */
19621
- getToolFunctions() {
19622
- return {
19623
- async get_current_time(args) {
19624
- var _a;
19625
- console.log('!!!! [Tool] get_current_time called', { args });
19626
- const { timezone } = args;
19627
- if (!timezone) {
19628
- return new Date().toISOString();
19629
- }
19630
- try {
19631
- // Note: Returning ISO 8601 string but in the requested timezone
19632
- const formatter = new Intl.DateTimeFormat('en-CA', {
19633
- timeZone: timezone,
19634
- year: 'numeric',
19635
- month: '2-digit',
19636
- day: '2-digit',
19637
- hour: '2-digit',
19638
- minute: '2-digit',
19639
- second: '2-digit',
19640
- hour12: false,
19641
- timeZoneName: 'shortOffset',
19642
- });
19643
- const parts = formatter.formatToParts(new Date());
19644
- const part = (type) => { var _a; return (_a = parts.find((p) => p.type === type)) === null || _a === void 0 ? void 0 : _a.value; };
19645
- // en-CA format is YYYY-MM-DD
19646
- 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', '')}`;
19647
- return isoString;
19648
- }
19649
- catch (error) {
19650
- // Fallback to UTC if timezone is invalid
19651
- return new Date().toISOString();
19652
- }
19653
- },
19654
- };
19655
- }
19656
- }
19657
- // Note: [💞] Ignore a discrepancy between file name and entity name
19658
-
19659
16719
  /**
19660
16720
  * Tool name used by the USE USER LOCATION commitment.
19661
16721
  *
@@ -19870,580 +16930,6 @@
19870
16930
  }
19871
16931
  // Note: [💞] Ignore a discrepancy between file name and entity name
19872
16932
 
19873
- /**
19874
- * Names of tools used by the WALLET commitment.
19875
- *
19876
- * @private constant of WalletCommitmentDefinition
19877
- */
19878
- const WalletToolNames = {
19879
- retrieve: 'retrieve_wallet_records',
19880
- store: 'store_wallet_record',
19881
- update: 'update_wallet_record',
19882
- delete: 'delete_wallet_record',
19883
- request: 'request_wallet_record',
19884
- };
19885
-
19886
- /**
19887
- * Creates WALLET system-message instructions.
19888
- *
19889
- * @private function of WalletCommitmentDefinition
19890
- */
19891
- function createWalletSystemMessage(extraInstructions) {
19892
- return spacetrim.spaceTrim((block) => `
19893
- Wallet:
19894
- - Use "${WalletToolNames.retrieve}" before authenticated operations.
19895
- - Use "${WalletToolNames.store}" and "${WalletToolNames.update}" to maintain credentials.
19896
- - Use "${WalletToolNames.delete}" to remove invalid credentials.
19897
- - Use "${WalletToolNames.request}" to request missing credentials via UI popup.
19898
- - Scope records by user (\`isUserScoped\`) and/or by agent (\`isGlobal=false\`) as needed.
19899
- - Never expose raw credentials in chat responses.
19900
- ${block(extraInstructions)}
19901
- `);
19902
- }
19903
-
19904
- /**
19905
- * Resolves disabled message for wallet runtime context.
19906
- *
19907
- * @private function of WalletCommitmentDefinition
19908
- */
19909
- function resolveWalletDisabledMessage(runtimeContext) {
19910
- if (runtimeContext.isPrivateMode) {
19911
- return 'Wallet is disabled because private mode is active.';
19912
- }
19913
- if (runtimeContext.isTeamConversation) {
19914
- return 'Wallet is disabled for TEAM conversations.';
19915
- }
19916
- if (!runtimeContext.enabled) {
19917
- return 'Wallet is disabled for unauthenticated users.';
19918
- }
19919
- return null;
19920
- }
19921
- /**
19922
- * Resolves runtime adapter for wallet tools or returns disabled payload when unavailable.
19923
- *
19924
- * @private function of WalletCommitmentDefinition
19925
- */
19926
- function getWalletToolRuntimeAdapterOrDisabledResult(action, runtimeContext) {
19927
- const disabledMessage = resolveWalletDisabledMessage(runtimeContext);
19928
- if (disabledMessage) {
19929
- return {
19930
- adapter: null,
19931
- disabledResult: {
19932
- action,
19933
- status: 'disabled',
19934
- records: action === 'retrieve' ? [] : undefined,
19935
- message: disabledMessage,
19936
- },
19937
- };
19938
- }
19939
- {
19940
- return {
19941
- adapter: null,
19942
- disabledResult: {
19943
- action,
19944
- status: 'disabled',
19945
- records: action === 'retrieve' ? [] : undefined,
19946
- message: 'Wallet runtime is not available in this environment.',
19947
- },
19948
- };
19949
- }
19950
- }
19951
-
19952
- /**
19953
- * Parses store/update wallet payload.
19954
- *
19955
- * @private function of WalletCommitmentDefinition
19956
- */
19957
- function parseWalletPayload(args) {
19958
- const recordType = parseWalletRecordType(args.recordType);
19959
- return {
19960
- recordType,
19961
- service: parseWalletService(args.service),
19962
- key: parseWalletKey(args.key),
19963
- isUserScoped: args.isUserScoped === true,
19964
- isGlobal: args.isGlobal === true,
19965
- ...parseWalletSecrets({
19966
- recordType,
19967
- username: args.username,
19968
- password: args.password,
19969
- secret: args.secret,
19970
- cookies: args.cookies,
19971
- }),
19972
- };
19973
- }
19974
- /**
19975
- * Parses text argument and returns trimmed text when available.
19976
- *
19977
- * @private function of WalletCommitmentDefinition
19978
- */
19979
- function normalizeOptionalText(value) {
19980
- if (typeof value !== 'string') {
19981
- return undefined;
19982
- }
19983
- const trimmed = value.trim();
19984
- return trimmed || undefined;
19985
- }
19986
- /**
19987
- * Parses wallet service argument.
19988
- *
19989
- * @private function of WalletCommitmentDefinition
19990
- */
19991
- function parseWalletService(value) {
19992
- return (normalizeOptionalText(value) || 'generic').toLowerCase();
19993
- }
19994
- /**
19995
- * Parses wallet key argument.
19996
- *
19997
- * @private function of WalletCommitmentDefinition
19998
- */
19999
- function parseWalletKey(value) {
20000
- return normalizeOptionalText(value) || 'default';
20001
- }
20002
- /**
20003
- * Parses one wallet record id argument.
20004
- *
20005
- * @private function of WalletCommitmentDefinition
20006
- */
20007
- function parseWalletId(value) {
20008
- const walletId = normalizeOptionalText(value);
20009
- if (!walletId) {
20010
- throw new Error('Wallet id is required.');
20011
- }
20012
- return walletId;
20013
- }
20014
- /**
20015
- * Parses wallet record type.
20016
- *
20017
- * @private function of WalletCommitmentDefinition
20018
- */
20019
- function parseWalletRecordType(value, fallback) {
20020
- var _a;
20021
- const normalizedType = (_a = normalizeOptionalText(value)) === null || _a === void 0 ? void 0 : _a.toUpperCase();
20022
- if (normalizedType === 'USERNAME_PASSWORD') {
20023
- return 'USERNAME_PASSWORD';
20024
- }
20025
- if (normalizedType === 'SESSION_COOKIE') {
20026
- return 'SESSION_COOKIE';
20027
- }
20028
- if (normalizedType === 'ACCESS_TOKEN') {
20029
- return 'ACCESS_TOKEN';
20030
- }
20031
- if (fallback) {
20032
- return fallback;
20033
- }
20034
- throw new Error('Unsupported wallet recordType. Expected one of: USERNAME_PASSWORD, SESSION_COOKIE, ACCESS_TOKEN.');
20035
- }
20036
- /**
20037
- * Parses wallet secret fields according to record type.
20038
- *
20039
- * @private function of WalletCommitmentDefinition
20040
- */
20041
- function parseWalletSecrets(args) {
20042
- const username = normalizeOptionalText(args.username);
20043
- const password = normalizeOptionalText(args.password);
20044
- const secret = normalizeOptionalText(args.secret);
20045
- const cookies = normalizeOptionalText(args.cookies);
20046
- if (args.recordType === 'USERNAME_PASSWORD') {
20047
- if (!username || !password) {
20048
- throw new Error('Both username and password are required for USERNAME_PASSWORD.');
20049
- }
20050
- return { username, password };
20051
- }
20052
- if (args.recordType === 'SESSION_COOKIE') {
20053
- if (!cookies) {
20054
- throw new Error('Cookies are required for SESSION_COOKIE.');
20055
- }
20056
- return { cookies };
20057
- }
20058
- if (!secret) {
20059
- throw new Error('Secret is required for ACCESS_TOKEN.');
20060
- }
20061
- return { secret };
20062
- }
20063
- /**
20064
- * Collection of WALLET tool argument parsers.
20065
- *
20066
- * @private function of WalletCommitmentDefinition
20067
- */
20068
- const parseWalletToolArgs = {
20069
- /**
20070
- * Parses retrieve arguments.
20071
- */
20072
- retrieve(args) {
20073
- const limit = typeof args.limit === 'number' && Number.isFinite(args.limit) ? Math.floor(args.limit) : undefined;
20074
- return {
20075
- query: normalizeOptionalText(args.query),
20076
- recordType: normalizeOptionalText(args.recordType) ? parseWalletRecordType(args.recordType) : undefined,
20077
- service: normalizeOptionalText(args.service) ? parseWalletService(args.service) : undefined,
20078
- key: normalizeOptionalText(args.key) ? parseWalletKey(args.key) : undefined,
20079
- limit: limit && limit > 0 ? Math.min(limit, 20) : undefined,
20080
- };
20081
- },
20082
- /**
20083
- * Parses store payload.
20084
- */
20085
- store(args) {
20086
- return parseWalletPayload(args);
20087
- },
20088
- /**
20089
- * Parses update payload.
20090
- */
20091
- update(args) {
20092
- const walletId = parseWalletId(args.walletId);
20093
- const record = parseWalletPayload(args);
20094
- return {
20095
- ...record,
20096
- walletId,
20097
- };
20098
- },
20099
- /**
20100
- * Parses delete payload.
20101
- */
20102
- delete(args) {
20103
- return { walletId: parseWalletId(args.walletId) };
20104
- },
20105
- /**
20106
- * Parses request payload for user wallet input prompt.
20107
- */
20108
- request(args) {
20109
- return {
20110
- recordType: parseWalletRecordType(args.recordType, 'ACCESS_TOKEN'),
20111
- service: parseWalletService(args.service),
20112
- key: parseWalletKey(args.key),
20113
- message: normalizeOptionalText(args.message),
20114
- isUserScoped: args.isUserScoped === true,
20115
- isGlobal: args.isGlobal === true,
20116
- };
20117
- },
20118
- };
20119
-
20120
- /**
20121
- * Resolves runtime context from hidden tool arguments.
20122
- *
20123
- * @private function of WalletCommitmentDefinition
20124
- */
20125
- function resolveWalletRuntimeContext(args) {
20126
- const runtimeContext = readToolRuntimeContextFromToolArgs(args);
20127
- const memoryContext = runtimeContext === null || runtimeContext === void 0 ? void 0 : runtimeContext.memory;
20128
- return {
20129
- enabled: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.enabled) === true,
20130
- userId: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.userId,
20131
- username: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.username,
20132
- agentId: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.agentId,
20133
- agentName: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.agentName,
20134
- isTeamConversation: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.isTeamConversation) === true,
20135
- isPrivateMode: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.isPrivateMode) === true,
20136
- };
20137
- }
20138
-
20139
- /**
20140
- * Creates runtime wallet tool function implementations.
20141
- *
20142
- * @private function of WalletCommitmentDefinition
20143
- */
20144
- function createWalletToolFunctions() {
20145
- return {
20146
- async [WalletToolNames.retrieve](args) {
20147
- const runtimeContext = resolveWalletRuntimeContext(args);
20148
- const { adapter, disabledResult } = getWalletToolRuntimeAdapterOrDisabledResult('retrieve', runtimeContext);
20149
- if (!adapter || disabledResult) {
20150
- return JSON.stringify(disabledResult);
20151
- }
20152
- try {
20153
- const parsedArgs = parseWalletToolArgs.retrieve(args);
20154
- const records = await adapter.retrieveWalletRecords(parsedArgs, runtimeContext);
20155
- return JSON.stringify({
20156
- action: 'retrieve',
20157
- status: 'ok',
20158
- query: parsedArgs.query,
20159
- records,
20160
- });
20161
- }
20162
- catch (error) {
20163
- return JSON.stringify({
20164
- action: 'retrieve',
20165
- status: 'error',
20166
- records: [],
20167
- message: error instanceof Error ? error.message : String(error),
20168
- });
20169
- }
20170
- },
20171
- async [WalletToolNames.store](args) {
20172
- const runtimeContext = resolveWalletRuntimeContext(args);
20173
- const { adapter, disabledResult } = getWalletToolRuntimeAdapterOrDisabledResult('store', runtimeContext);
20174
- if (!adapter || disabledResult) {
20175
- return JSON.stringify(disabledResult);
20176
- }
20177
- try {
20178
- const parsedArgs = parseWalletToolArgs.store(args);
20179
- const record = await adapter.storeWalletRecord(parsedArgs, runtimeContext);
20180
- return JSON.stringify({
20181
- action: 'store',
20182
- status: 'stored',
20183
- record,
20184
- });
20185
- }
20186
- catch (error) {
20187
- return JSON.stringify({
20188
- action: 'store',
20189
- status: 'error',
20190
- message: error instanceof Error ? error.message : String(error),
20191
- });
20192
- }
20193
- },
20194
- async [WalletToolNames.update](args) {
20195
- const runtimeContext = resolveWalletRuntimeContext(args);
20196
- const { adapter, disabledResult } = getWalletToolRuntimeAdapterOrDisabledResult('update', runtimeContext);
20197
- if (!adapter || disabledResult) {
20198
- return JSON.stringify(disabledResult);
20199
- }
20200
- try {
20201
- const parsedArgs = parseWalletToolArgs.update(args);
20202
- const record = await adapter.updateWalletRecord(parsedArgs, runtimeContext);
20203
- return JSON.stringify({
20204
- action: 'update',
20205
- status: 'updated',
20206
- record,
20207
- });
20208
- }
20209
- catch (error) {
20210
- return JSON.stringify({
20211
- action: 'update',
20212
- status: 'error',
20213
- message: error instanceof Error ? error.message : String(error),
20214
- });
20215
- }
20216
- },
20217
- async [WalletToolNames.delete](args) {
20218
- const runtimeContext = resolveWalletRuntimeContext(args);
20219
- const { adapter, disabledResult } = getWalletToolRuntimeAdapterOrDisabledResult('delete', runtimeContext);
20220
- if (!adapter || disabledResult) {
20221
- return JSON.stringify(disabledResult);
20222
- }
20223
- try {
20224
- const parsedArgs = parseWalletToolArgs.delete(args);
20225
- const deleted = await adapter.deleteWalletRecord(parsedArgs, runtimeContext);
20226
- return JSON.stringify({
20227
- action: 'delete',
20228
- status: 'deleted',
20229
- walletId: deleted.id,
20230
- });
20231
- }
20232
- catch (error) {
20233
- return JSON.stringify({
20234
- action: 'delete',
20235
- status: 'error',
20236
- message: error instanceof Error ? error.message : String(error),
20237
- });
20238
- }
20239
- },
20240
- async [WalletToolNames.request](args) {
20241
- const runtimeContext = resolveWalletRuntimeContext(args);
20242
- const disabledMessage = resolveWalletDisabledMessage(runtimeContext);
20243
- if (disabledMessage) {
20244
- return JSON.stringify({
20245
- action: 'request',
20246
- status: 'disabled',
20247
- message: disabledMessage,
20248
- });
20249
- }
20250
- const request = parseWalletToolArgs.request(args);
20251
- return JSON.stringify({
20252
- action: 'request',
20253
- status: 'requested',
20254
- request,
20255
- message: request.message ||
20256
- `Request user to provide ${request.recordType} credentials for service "${request.service}".`,
20257
- });
20258
- },
20259
- };
20260
- }
20261
-
20262
- /**
20263
- * Creates tool definitions required by WALLET commitment.
20264
- *
20265
- * @private function of WalletCommitmentDefinition
20266
- */
20267
- function createWalletTools(existingTools) {
20268
- const tools = [...(existingTools || [])];
20269
- addWalletToolIfMissing(tools, {
20270
- name: WalletToolNames.retrieve,
20271
- description: 'Retrieve wallet records relevant to the current task.',
20272
- parameters: {
20273
- type: 'object',
20274
- properties: {
20275
- query: { type: 'string', description: 'Optional text query used to filter wallet records.' },
20276
- recordType: {
20277
- type: 'string',
20278
- description: 'Optional record type filter (USERNAME_PASSWORD, SESSION_COOKIE, ACCESS_TOKEN).',
20279
- },
20280
- service: { type: 'string', description: 'Optional service filter, for example github.' },
20281
- key: { type: 'string', description: 'Optional wallet key filter.' },
20282
- limit: { type: 'integer', description: 'Optional maximum number of records (default 5, max 20).' },
20283
- },
20284
- required: [],
20285
- },
20286
- });
20287
- addWalletToolIfMissing(tools, {
20288
- name: WalletToolNames.store,
20289
- description: 'Store one wallet record.',
20290
- parameters: {
20291
- type: 'object',
20292
- properties: {
20293
- recordType: {
20294
- type: 'string',
20295
- description: 'Record type: USERNAME_PASSWORD, SESSION_COOKIE, ACCESS_TOKEN.',
20296
- },
20297
- service: { type: 'string', description: 'Service identifier, for example github.' },
20298
- key: { type: 'string', description: 'Logical credential key.' },
20299
- username: { type: 'string', description: 'Username for USERNAME_PASSWORD.' },
20300
- password: { type: 'string', description: 'Password for USERNAME_PASSWORD.' },
20301
- secret: { type: 'string', description: 'Token/API key for ACCESS_TOKEN.' },
20302
- cookies: { type: 'string', description: 'Cookie header/json for SESSION_COOKIE.' },
20303
- isUserScoped: { type: 'boolean', description: 'Set true to scope this record to current user.' },
20304
- isGlobal: { type: 'boolean', description: 'Set true to make this record global.' },
20305
- },
20306
- required: ['recordType', 'service'],
20307
- },
20308
- });
20309
- addWalletToolIfMissing(tools, {
20310
- name: WalletToolNames.update,
20311
- description: 'Update one existing wallet record.',
20312
- parameters: {
20313
- type: 'object',
20314
- properties: {
20315
- walletId: { type: 'string', description: 'Wallet record id to update.' },
20316
- recordType: {
20317
- type: 'string',
20318
- description: 'Record type: USERNAME_PASSWORD, SESSION_COOKIE, ACCESS_TOKEN.',
20319
- },
20320
- service: { type: 'string', description: 'Service identifier, for example github.' },
20321
- key: { type: 'string', description: 'Logical credential key.' },
20322
- username: { type: 'string', description: 'Username for USERNAME_PASSWORD.' },
20323
- password: { type: 'string', description: 'Password for USERNAME_PASSWORD.' },
20324
- secret: { type: 'string', description: 'Token/API key for ACCESS_TOKEN.' },
20325
- cookies: { type: 'string', description: 'Cookie header/json for SESSION_COOKIE.' },
20326
- isUserScoped: { type: 'boolean', description: 'Set true to scope this record to current user.' },
20327
- isGlobal: { type: 'boolean', description: 'Set true to make this record global.' },
20328
- },
20329
- required: ['walletId', 'recordType', 'service'],
20330
- },
20331
- });
20332
- addWalletToolIfMissing(tools, {
20333
- name: WalletToolNames.delete,
20334
- description: 'Delete one wallet record.',
20335
- parameters: {
20336
- type: 'object',
20337
- properties: {
20338
- walletId: { type: 'string', description: 'Wallet record id to delete.' },
20339
- },
20340
- required: ['walletId'],
20341
- },
20342
- });
20343
- addWalletToolIfMissing(tools, {
20344
- name: WalletToolNames.request,
20345
- description: 'Request missing credential from user via popup.',
20346
- parameters: {
20347
- type: 'object',
20348
- properties: {
20349
- recordType: {
20350
- type: 'string',
20351
- description: 'Requested record type: USERNAME_PASSWORD, SESSION_COOKIE, ACCESS_TOKEN.',
20352
- },
20353
- service: { type: 'string', description: 'Service identifier.' },
20354
- key: { type: 'string', description: 'Logical credential key.' },
20355
- message: { type: 'string', description: 'Optional UI message for user.' },
20356
- isUserScoped: {
20357
- type: 'boolean',
20358
- description: 'Set true when record should be scoped to current user.',
20359
- },
20360
- isGlobal: { type: 'boolean', description: 'Set true when record should be global.' },
20361
- },
20362
- required: [],
20363
- },
20364
- });
20365
- return tools;
20366
- }
20367
- /**
20368
- * Registers one wallet tool when missing in current tool list.
20369
- *
20370
- * @private function of WalletCommitmentDefinition
20371
- */
20372
- function addWalletToolIfMissing(tools, tool) {
20373
- if (!tools.some((existingTool) => existingTool.name === tool.name)) {
20374
- tools.push(tool);
20375
- }
20376
- }
20377
-
20378
- /**
20379
- * Gets markdown documentation for WALLET commitment.
20380
- *
20381
- * @private function of WalletCommitmentDefinition
20382
- */
20383
- function getWalletCommitmentDocumentation(type) {
20384
- return spacetrim.spaceTrim(`
20385
- # ${type}
20386
-
20387
- Enables private credential storage for tokens, usernames/passwords, and session cookies.
20388
- `);
20389
- }
20390
-
20391
- /**
20392
- * Gets human-readable titles for WALLET tool functions.
20393
- *
20394
- * @private function of WalletCommitmentDefinition
20395
- */
20396
- function getWalletToolTitles() {
20397
- return {
20398
- [WalletToolNames.retrieve]: 'Wallet',
20399
- [WalletToolNames.store]: 'Store wallet record',
20400
- [WalletToolNames.update]: 'Update wallet record',
20401
- [WalletToolNames.delete]: 'Delete wallet record',
20402
- [WalletToolNames.request]: 'Request wallet record',
20403
- };
20404
- }
20405
-
20406
- /**
20407
- * WALLET commitment definition.
20408
- *
20409
- * @private [🪔] Maybe export the commitments through some package
20410
- */
20411
- class WalletCommitmentDefinition extends BaseCommitmentDefinition {
20412
- constructor(type = 'WALLET') {
20413
- super(type);
20414
- }
20415
- get requiresContent() {
20416
- return false;
20417
- }
20418
- get description() {
20419
- return 'Enable persistent private credential storage (tokens, logins, cookies) scoped per agent or globally.';
20420
- }
20421
- get icon() {
20422
- return '👛';
20423
- }
20424
- get documentation() {
20425
- return getWalletCommitmentDocumentation(this.type);
20426
- }
20427
- applyToAgentModelRequirements(requirements, content) {
20428
- const extraInstructions = formatOptionalInstructionBlock('Wallet instructions', content);
20429
- return this.appendToSystemMessage({
20430
- ...requirements,
20431
- tools: createWalletTools(requirements.tools),
20432
- _metadata: {
20433
- ...requirements._metadata,
20434
- useWallet: content || true,
20435
- },
20436
- }, createWalletSystemMessage(extraInstructions));
20437
- }
20438
- getToolTitles() {
20439
- return getWalletToolTitles();
20440
- }
20441
- getToolFunctions() {
20442
- return createWalletToolFunctions();
20443
- }
20444
- }
20445
- // Note: [💞] Ignore a discrepancy between file name and entity name
20446
-
20447
16933
  /**
20448
16934
  * `WRITING RULES` commitment definition.
20449
16935
  *
@@ -20670,8 +17156,6 @@
20670
17156
  new PersonaCommitmentDefinition('PERSONA'),
20671
17157
  new PersonaCommitmentDefinition('PERSONAE'),
20672
17158
  new KnowledgeCommitmentDefinition(),
20673
- new MemoryCommitmentDefinition('MEMORY'),
20674
- new MemoryCommitmentDefinition('MEMORIES'),
20675
17159
  new StyleCommitmentDefinition('STYLE'),
20676
17160
  new StyleCommitmentDefinition('STYLES'),
20677
17161
  new RuleCommitmentDefinition('RULE'),
@@ -20693,7 +17177,6 @@
20693
17177
  new ModelCommitmentDefinition('MODELS'),
20694
17178
  new ActionCommitmentDefinition('ACTION'),
20695
17179
  new ActionCommitmentDefinition('ACTIONS'),
20696
- new ComponentCommitmentDefinition(),
20697
17180
  new MetaAvatarCommitmentDefinition(),
20698
17181
  new MetaAvatarCommitmentDefinition('META VISUAL'),
20699
17182
  new MetaImageCommitmentDefinition(),
@@ -20701,11 +17184,13 @@
20701
17184
  new MetaFontCommitmentDefinition(),
20702
17185
  new MetaLinkCommitmentDefinition(),
20703
17186
  new MetaDomainCommitmentDefinition(),
17187
+ new MetaDescriptionCommitmentDefinition(),
20704
17188
  new MetaDisclaimerCommitmentDefinition(),
17189
+ new MetaFullnameCommitmentDefinition(),
17190
+ new MetaIdCommitmentDefinition(),
20705
17191
  new MetaInputPlaceholderCommitmentDefinition(),
20706
17192
  new MetaThinkingMessageCommitmentDefinition(),
20707
17193
  new MetaVisibilityCommitmentDefinition(),
20708
- new MetaCommitmentDefinition(),
20709
17194
  new MetaVoiceCommitmentDefinition(),
20710
17195
  new NoteCommitmentDefinition('NOTE'),
20711
17196
  new NoteCommitmentDefinition('NOTES'),
@@ -20721,8 +17206,6 @@
20721
17206
  new MessageSuffixCommitmentDefinition(),
20722
17207
  new MessageCommitmentDefinition('MESSAGE'),
20723
17208
  new MessageCommitmentDefinition('MESSAGES'),
20724
- new WalletCommitmentDefinition('WALLET'),
20725
- new WalletCommitmentDefinition('WALLETS'),
20726
17209
  new ScenarioCommitmentDefinition('SCENARIO'),
20727
17210
  new ScenarioCommitmentDefinition('SCENARIOS'),
20728
17211
  new DeleteCommitmentDefinition('DELETE'),
@@ -20733,15 +17216,8 @@
20733
17216
  new OpenCommitmentDefinition(),
20734
17217
  new ClosedCommitmentDefinition(),
20735
17218
  new TeamCommitmentDefinition(),
20736
- new UseBrowserCommitmentDefinition(),
20737
- new UseDeepSearchCommitmentDefinition(),
20738
- new UseSearchEngineCommitmentDefinition(),
20739
- new UseSpawnCommitmentDefinition(),
20740
- new UseTimeoutCommitmentDefinition(),
20741
- new UseTimeCommitmentDefinition(),
20742
17219
  new UseUserLocationCommitmentDefinition(),
20743
17220
  new UseCalendarCommitmentDefinition(),
20744
- new UseEmailCommitmentDefinition(),
20745
17221
  new UsePopupCommitmentDefinition(),
20746
17222
  new UseImageGeneratorCommitmentDefinition('USE IMAGE GENERATOR'),
20747
17223
  new UseMcpCommitmentDefinition(),
@@ -20937,6 +17413,39 @@
20937
17413
  return commitmentToolFunctionsProxy;
20938
17414
  }
20939
17415
 
17416
+ /**
17417
+ * Generates random token
17418
+ *
17419
+ * Note: `$` is used to indicate that this function is not a pure function - it is not deterministic
17420
+ * Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
17421
+ *
17422
+ * @returns secure random token
17423
+ *
17424
+ * @private internal helper function
17425
+ */
17426
+ function $randomToken(randomness) {
17427
+ return CryptoJS__default["default"].lib.WordArray.random(randomness).toString(CryptoJS__default["default"].enc.Hex);
17428
+ }
17429
+ // TODO: [🤶] Maybe export through `@promptbook/utils` or `@promptbook/random` package
17430
+ // TODO: Maybe use nanoid instead https://github.com/ai/nanoid
17431
+
17432
+ /**
17433
+ * This error indicates errors during the execution of the pipeline
17434
+ *
17435
+ * @public exported from `@promptbook/core`
17436
+ */
17437
+ class PipelineExecutionError extends Error {
17438
+ constructor(message) {
17439
+ // Added id parameter
17440
+ super(message);
17441
+ this.name = 'PipelineExecutionError';
17442
+ // TODO: [🐙] DRY - Maybe $randomId
17443
+ this.id = `error-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid similar char conflicts */)}`;
17444
+ Object.setPrototypeOf(this, PipelineExecutionError.prototype);
17445
+ }
17446
+ }
17447
+ // TODO: [🧠][🌂] Add id to all errors
17448
+
20940
17449
  /**
20941
17450
  * Wrapper around `window.prompt` synchronous function that interacts with the user via browser prompt
20942
17451
  *
@@ -22253,59 +18762,6 @@
22253
18762
  return initialMessage;
22254
18763
  }
22255
18764
 
22256
- /**
22257
- * Normalizes a given text to camelCase format.
22258
- *
22259
- * Note: [🔂] This function is idempotent.
22260
- *
22261
- * @param text The text to be normalized.
22262
- * @param _isFirstLetterCapital Whether the first letter should be capitalized.
22263
- * @returns The camelCase formatted string.
22264
- * @example 'helloWorld'
22265
- * @example 'iLovePromptbook'
22266
- *
22267
- * @public exported from `@promptbook/utils`
22268
- */
22269
- function normalizeTo_camelCase(text, _isFirstLetterCapital = false) {
22270
- let charType;
22271
- let lastCharType = null;
22272
- let normalizedName = '';
22273
- for (const char of text) {
22274
- let normalizedChar;
22275
- if (/^[a-z]$/.test(char)) {
22276
- charType = 'LOWERCASE';
22277
- normalizedChar = char;
22278
- }
22279
- else if (/^[A-Z]$/.test(char)) {
22280
- charType = 'UPPERCASE';
22281
- normalizedChar = char.toLowerCase();
22282
- }
22283
- else if (/^[0-9]$/.test(char)) {
22284
- charType = 'NUMBER';
22285
- normalizedChar = char;
22286
- }
22287
- else {
22288
- charType = 'OTHER';
22289
- normalizedChar = '';
22290
- }
22291
- if (!lastCharType) {
22292
- if (_isFirstLetterCapital) {
22293
- normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
22294
- }
22295
- }
22296
- else if (charType !== lastCharType &&
22297
- !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
22298
- !(lastCharType === 'NUMBER') &&
22299
- !(charType === 'NUMBER')) {
22300
- normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
22301
- }
22302
- normalizedName += normalizedChar;
22303
- lastCharType = charType;
22304
- }
22305
- return normalizedName;
22306
- }
22307
- // TODO: [🌺] Use some intermediate util splitWords
22308
-
22309
18765
  /**
22310
18766
  * Normalizes a domain-like string into a comparable hostname form.
22311
18767
  *
@@ -22344,6 +18800,54 @@
22344
18800
  return value.startsWith('http://') || value.startsWith('https://');
22345
18801
  }
22346
18802
 
18803
+ /**
18804
+ * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
18805
+ *
18806
+ * @public exported from `@promptbook/core`
18807
+ */
18808
+ class ParseError extends Error {
18809
+ constructor(message) {
18810
+ super(message);
18811
+ this.name = 'ParseError';
18812
+ Object.setPrototypeOf(this, ParseError.prototype);
18813
+ }
18814
+ }
18815
+ // TODO: Maybe split `ParseError` and `ApplyError`
18816
+
18817
+ /**
18818
+ * Supported visibility states for persisted agents.
18819
+ *
18820
+ * @public exported from `@promptbook/core`
18821
+ */
18822
+ const AGENT_VISIBILITY_VALUES = ['PRIVATE', 'UNLISTED', 'PUBLIC'];
18823
+ /**
18824
+ * Returns `true` when the value is one of supported visibility states.
18825
+ *
18826
+ * @param value - Raw value to validate.
18827
+ * @returns Whether the value is a valid `AgentVisibility`.
18828
+ *
18829
+ * @public exported from `@promptbook/core`
18830
+ */
18831
+ function isAgentVisibility(value) {
18832
+ return typeof value === 'string' && AGENT_VISIBILITY_VALUES.includes(value);
18833
+ }
18834
+ /**
18835
+ * Normalizes raw visibility text into a supported value.
18836
+ *
18837
+ * @param value - Raw visibility value.
18838
+ * @returns Normalized visibility, or `null` when invalid.
18839
+ *
18840
+ * @public exported from `@promptbook/core`
18841
+ */
18842
+ function normalizeAgentVisibility(value) {
18843
+ if (typeof value !== 'string') {
18844
+ return null;
18845
+ }
18846
+ const normalized = value.trim().toUpperCase();
18847
+ return isAgentVisibility(normalized) ? normalized : null;
18848
+ }
18849
+ // Note: [💞] Ignore a discrepancy between file name and entity name
18850
+
22347
18851
  /**
22348
18852
  * Dedicated handlers for META-style commitments that directly map onto parsed meta fields.
22349
18853
  */
@@ -22355,6 +18859,8 @@
22355
18859
  'META IMAGE': applyMetaImageContent,
22356
18860
  'META DESCRIPTION': applyMetaDescriptionContent,
22357
18861
  'META DISCLAIMER': applyMetaDisclaimerContent,
18862
+ 'META FULLNAME': applyMetaFullnameContent,
18863
+ 'META ID': applyMetaIdContent,
22358
18864
  'META INPUT PLACEHOLDER': applyMetaInputPlaceholderContent,
22359
18865
  'META THINKING MESSAGE': applyMetaThinkingMessageContent,
22360
18866
  'MESSAGE SUFFIX': applyMessageSuffixContent,
@@ -22372,32 +18878,8 @@
22372
18878
  const applyMetaContent = META_COMMITMENT_APPLIERS[commitment.type];
22373
18879
  if (applyMetaContent) {
22374
18880
  applyMetaContent(state, commitment.content);
22375
- return;
22376
- }
22377
- if (commitment.type === 'META') {
22378
- applyGenericMetaCommitment(state, commitment.content);
22379
18881
  }
22380
18882
  }
22381
- /**
22382
- * Applies the generic META commitment form (`META TYPE value`).
22383
- */
22384
- function applyGenericMetaCommitment(state, content) {
22385
- const metaTypeRaw = content.split(' ')[0] || 'NONE';
22386
- const metaValue = spacetrim.spaceTrim(content.substring(metaTypeRaw.length));
22387
- if (metaTypeRaw === 'LINK') {
22388
- state.links.push(metaValue);
22389
- }
22390
- if (metaTypeRaw.toUpperCase() === 'AVATAR') {
22391
- applyMetaAvatarContent(state, metaValue);
22392
- return;
22393
- }
22394
- if (metaTypeRaw.toUpperCase() === 'VISIBILITY') {
22395
- applyMetaVisibilityContent(state, metaValue);
22396
- return;
22397
- }
22398
- const metaType = normalizeTo_camelCase(metaTypeRaw);
22399
- state.meta[metaType] = metaValue;
22400
- }
22401
18883
  /**
22402
18884
  * Applies META AVATAR / META VISUAL content into the canonical `meta.avatar` field.
22403
18885
  */
@@ -22441,6 +18923,18 @@
22441
18923
  function applyMetaDisclaimerContent(state, content) {
22442
18924
  state.meta.disclaimer = content;
22443
18925
  }
18926
+ /**
18927
+ * Applies META FULLNAME content into the canonical `meta.fullname` field.
18928
+ */
18929
+ function applyMetaFullnameContent(state, content) {
18930
+ state.meta.fullname = spacetrim.spaceTrim(content);
18931
+ }
18932
+ /**
18933
+ * Applies META ID content into the canonical `meta.id` field.
18934
+ */
18935
+ function applyMetaIdContent(state, content) {
18936
+ state.meta.id = spacetrim.spaceTrim(content);
18937
+ }
22444
18938
  /**
22445
18939
  * Applies META INPUT PLACEHOLDER content into the canonical `meta.inputPlaceholder` field.
22446
18940
  */
@@ -22545,46 +19039,11 @@
22545
19039
  * Static capability descriptors for commitments that map one-to-one to a visible capability.
22546
19040
  */
22547
19041
  const SIMPLE_CAPABILITY_BY_COMMITMENT_TYPE = {
22548
- 'USE BROWSER': {
22549
- type: 'browser',
22550
- label: 'Browser',
22551
- iconName: 'Globe',
22552
- },
22553
- 'USE SEARCH ENGINE': {
22554
- type: 'search-engine',
22555
- label: 'Internet',
22556
- iconName: 'Search',
22557
- },
22558
- 'USE SEARCH': {
22559
- type: 'search-engine',
22560
- label: 'Internet',
22561
- iconName: 'Search',
22562
- },
22563
- 'USE DEEPSEARCH': {
22564
- type: 'search-engine',
22565
- label: 'DeepSearch',
22566
- iconName: 'Search',
22567
- },
22568
- 'USE TIME': {
22569
- type: 'time',
22570
- label: 'Time',
22571
- iconName: 'Clock',
22572
- },
22573
- 'USE TIMEOUT': {
22574
- type: 'timeout',
22575
- label: 'Timers',
22576
- iconName: 'Clock',
22577
- },
22578
19042
  'USE USER LOCATION': {
22579
19043
  type: 'user-location',
22580
19044
  label: 'User location',
22581
19045
  iconName: 'MapPin',
22582
19046
  },
22583
- 'USE EMAIL': {
22584
- type: 'email',
22585
- label: 'Email',
22586
- iconName: 'Mail',
22587
- },
22588
19047
  'USE POPUP': {
22589
19048
  type: 'popup',
22590
19049
  label: 'Popup',
@@ -23094,6 +19553,21 @@
23094
19553
  // <- [🐱‍🚀] Buttons into genesis book
23095
19554
  // <- TODO: [🐱‍🚀] generateBookBoilerplate and deprecate `DEFAULT_BOOK`
23096
19555
 
19556
+ /**
19557
+ * Checks if value is valid email
19558
+ *
19559
+ * @public exported from `@promptbook/utils`
19560
+ */
19561
+ function isValidEmail(email) {
19562
+ if (typeof email !== 'string') {
19563
+ return false;
19564
+ }
19565
+ if (email.split(/\r?\n/).length > 1) {
19566
+ return false;
19567
+ }
19568
+ return /^.+@.+\..+$/.test(email);
19569
+ }
19570
+
23097
19571
  /**
23098
19572
  * Function isValidJsonString will tell you if the string is valid JSON or not
23099
19573
  *
@@ -23167,6 +19641,19 @@
23167
19641
  }
23168
19642
  // TODO: [🧠][🈴] Where is the best location for this file
23169
19643
 
19644
+ /**
19645
+ * This error type indicates that some limit was reached
19646
+ *
19647
+ * @public exported from `@promptbook/core`
19648
+ */
19649
+ class LimitReachedError extends Error {
19650
+ constructor(message) {
19651
+ super(message);
19652
+ this.name = 'LimitReachedError';
19653
+ Object.setPrototypeOf(this, LimitReachedError.prototype);
19654
+ }
19655
+ }
19656
+
23170
19657
  /**
23171
19658
  * Replaces parameters in template with values from parameters object
23172
19659
  *
@@ -30218,12 +26705,6 @@
30218
26705
  ['GOAL', 'GOAL'],
30219
26706
  ['GOALS', 'GOAL'],
30220
26707
  ]);
30221
- /**
30222
- * Legacy commitments that should be parsed for compatibility but ignored by the model-requirements pipeline.
30223
- *
30224
- * @private internal constant of `filterCommitmentsForAgentModelRequirements`
30225
- */
30226
- const IGNORED_COMMITMENT_TYPES = new Set(['WALLET', 'WALLETS']);
30227
26708
  /**
30228
26709
  * Applies the commitment filtering rules used before commitment definitions are executed.
30229
26710
  *
@@ -30272,9 +26753,6 @@
30272
26753
  function filterDeletedCommitments(commitments) {
30273
26754
  const filteredCommitments = [];
30274
26755
  for (const commitment of commitments) {
30275
- if (isIgnoredCommitmentType(commitment.type)) {
30276
- continue;
30277
- }
30278
26756
  if (!isDeleteCommitmentType(commitment.type)) {
30279
26757
  filteredCommitments.push(commitment);
30280
26758
  continue;
@@ -30305,17 +26783,6 @@
30305
26783
  function isDeleteCommitmentType(commitmentType) {
30306
26784
  return DELETE_COMMITMENT_TYPES.has(commitmentType);
30307
26785
  }
30308
- /**
30309
- * Checks whether a parsed commitment is intentionally ignored by the current model compiler.
30310
- *
30311
- * @param commitmentType - Commitment type to check.
30312
- * @returns `true` when the commitment should not affect model requirements.
30313
- *
30314
- * @private internal utility of `filterDeletedCommitments`
30315
- */
30316
- function isIgnoredCommitmentType(commitmentType) {
30317
- return IGNORED_COMMITMENT_TYPES.has(commitmentType);
30318
- }
30319
26786
  /**
30320
26787
  * Extracts normalized parameter names used for DELETE-like invalidation matching.
30321
26788
  *
@@ -30449,7 +26916,6 @@
30449
26916
  const filteredCommitments = filterCommitmentsForAgentModelRequirements(parseResult.commitments);
30450
26917
  let requirements = createInitialAgentModelRequirements(parseResult.agentName, modelName);
30451
26918
  requirements = await applyCommitmentsToAgentModelRequirements(requirements, filteredCommitments, options);
30452
- requirements = aggregateUseCommitmentSystemMessages(requirements, filteredCommitments);
30453
26919
  requirements = await augmentAgentModelRequirementsFromSource(requirements, parseResult, agentSource);
30454
26920
  requirements = await materializeInlineKnowledgeSources(requirements, options === null || options === void 0 ? void 0 : options.inlineKnowledgeSourceUploader);
30455
26921
  return finalizeRequirements(requirements);
@@ -31126,6 +27592,40 @@
31126
27592
  }
31127
27593
  }
31128
27594
 
27595
+ /**
27596
+ * Marker property stored inside serialized tool-execution envelopes.
27597
+ *
27598
+ * @private internal tool-execution transport
27599
+ */
27600
+ const TOOL_EXECUTION_ENVELOPE_MARKER = '__promptbookToolExecutionEnvelope';
27601
+ /**
27602
+ * Parses one serialized tool-execution envelope when present.
27603
+ *
27604
+ * @private internal tool-execution transport
27605
+ */
27606
+ function parseToolExecutionEnvelope(rawValue) {
27607
+ if (typeof rawValue !== 'string') {
27608
+ return null;
27609
+ }
27610
+ try {
27611
+ const parsedValue = JSON.parse(rawValue);
27612
+ if (!parsedValue ||
27613
+ typeof parsedValue !== 'object' ||
27614
+ parsedValue[TOOL_EXECUTION_ENVELOPE_MARKER] !== true ||
27615
+ typeof parsedValue.assistantMessage !== 'string') {
27616
+ return null;
27617
+ }
27618
+ return {
27619
+ assistantMessage: parsedValue.assistantMessage,
27620
+ toolResult: parsedValue.toolResult,
27621
+ };
27622
+ }
27623
+ catch (_a) {
27624
+ return null;
27625
+ }
27626
+ }
27627
+ // Note: [💞] Ignore a discrepancy between file name and entity name
27628
+
31129
27629
  /**
31130
27630
  * Builds a tool invocation script that injects hidden runtime context into tool args.
31131
27631
  *
@@ -31197,7 +27697,7 @@
31197
27697
  */
31198
27698
  const DEFAULT_DEEP_SEARCH_MODEL_NAME = 'o4-mini-deep-research';
31199
27699
  /**
31200
- * Tool name used by the Book commitment-backed DeepSearch capability.
27700
+ * Tool name used by the DeepSearch capability.
31201
27701
  */
31202
27702
  const DEEP_SEARCH_TOOL_NAME = 'deep_search';
31203
27703
  /**
@@ -31467,7 +27967,7 @@
31467
27967
  };
31468
27968
  }
31469
27969
  /**
31470
- * Creates the native Agent SDK tool used for `USE DEEPSEARCH`.
27970
+ * Creates the native Agent SDK tool used for the DeepSearch capability.
31471
27971
  */
31472
27972
  async createDeepSearchAgentKitTool(toolDefinition) {
31473
27973
  const { Agent: AgentFromKit, webSearchTool } = await loadOpenAiAgentsModule();
@@ -39564,7 +36064,7 @@
39564
36064
  this.links = [];
39565
36065
  /**
39566
36066
  * Capabilities of the agent
39567
- * This is parsed from commitments like USE BROWSER, USE SEARCH ENGINE, KNOWLEDGE, etc.
36067
+ * This is parsed from commitments like USE CALENDAR, USE PROJECT, KNOWLEDGE, etc.
39568
36068
  */
39569
36069
  this.capabilities = [];
39570
36070
  /**