@promptbook/browser 0.103.0-1 → 0.103.0-100

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 (258) hide show
  1. package/README.md +153 -89
  2. package/esm/index.es.js +4514 -125
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/books/index.d.ts +0 -81
  5. package/esm/typings/servers.d.ts +9 -7
  6. package/esm/typings/src/_packages/browser.index.d.ts +6 -0
  7. package/esm/typings/src/_packages/cli.index.d.ts +4 -0
  8. package/esm/typings/src/_packages/components.index.d.ts +20 -8
  9. package/esm/typings/src/_packages/core.index.d.ts +58 -18
  10. package/esm/typings/src/_packages/node.index.d.ts +2 -2
  11. package/esm/typings/src/_packages/remote-server.index.d.ts +2 -0
  12. package/esm/typings/src/_packages/types.index.d.ts +58 -8
  13. package/esm/typings/src/_packages/utils.index.d.ts +6 -0
  14. package/esm/typings/src/_packages/wizard.index.d.ts +4 -0
  15. package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +19 -5
  16. package/esm/typings/src/book-2.0/agent-source/AgentModelRequirements.d.ts +17 -1
  17. package/esm/typings/src/book-2.0/agent-source/AgentSourceParseResult.d.ts +3 -2
  18. package/esm/typings/src/book-2.0/agent-source/computeAgentHash.d.ts +8 -0
  19. package/esm/typings/src/book-2.0/agent-source/createCommitmentRegex.d.ts +3 -3
  20. package/esm/typings/src/book-2.0/agent-source/createDefaultAgentName.d.ts +8 -0
  21. package/esm/typings/src/book-2.0/agent-source/normalizeAgentName.d.ts +9 -0
  22. package/esm/typings/src/book-2.0/agent-source/padBook.d.ts +18 -0
  23. package/esm/typings/src/book-2.0/agent-source/parseAgentSourceWithCommitments.d.ts +1 -1
  24. package/esm/typings/src/book-2.0/agent-source/string_book.d.ts +3 -0
  25. package/esm/typings/src/book-components/AvatarProfile/AvatarProfile/AvatarProfile.d.ts +10 -0
  26. package/esm/typings/src/book-components/AvatarProfile/AvatarProfile/AvatarProfileTooltip.d.ts +15 -0
  27. package/esm/typings/src/book-components/BookEditor/BookEditor.d.ts +83 -8
  28. package/esm/typings/src/book-components/BookEditor/BookEditorActionbar.d.ts +14 -0
  29. package/esm/typings/src/book-components/BookEditor/BookEditorMonaco.d.ts +5 -0
  30. package/esm/typings/src/book-components/Chat/AgentChat/AgentChat.d.ts +14 -0
  31. package/esm/typings/src/book-components/Chat/AgentChat/AgentChatProps.d.ts +13 -0
  32. package/esm/typings/src/book-components/Chat/Chat/ChatProps.d.ts +10 -0
  33. package/esm/typings/src/book-components/Chat/LlmChat/LlmChatProps.d.ts +5 -0
  34. package/esm/typings/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +15 -0
  35. package/esm/typings/src/book-components/Chat/MockedChat/MockedChat.d.ts +5 -0
  36. package/esm/typings/src/book-components/Chat/save/_common/ChatSaveFormatDefinition.d.ts +1 -1
  37. package/esm/typings/src/book-components/Chat/save/html/htmlSaveFormatDefinition.d.ts +1 -0
  38. package/esm/typings/src/book-components/Chat/save/pdf/pdfSaveFormatDefinition.d.ts +4 -0
  39. package/esm/typings/src/book-components/Chat/types/ChatParticipant.d.ts +5 -0
  40. package/esm/typings/src/book-components/PromptbookAgent/PromptbookAgent.d.ts +29 -0
  41. package/esm/typings/src/book-components/Qr/BrandedQrCode.d.ts +18 -0
  42. package/esm/typings/src/book-components/Qr/GenericQrCode.d.ts +10 -0
  43. package/esm/typings/src/book-components/Qr/PromptbookQrCode.d.ts +18 -0
  44. package/esm/typings/src/book-components/Qr/useQrCode.d.ts +15 -0
  45. package/esm/typings/src/book-components/_common/Dropdown/Dropdown.d.ts +15 -0
  46. package/esm/typings/src/book-components/_common/HamburgerMenu/HamburgerMenu.d.ts +12 -0
  47. package/esm/typings/src/book-components/_common/Modal/Modal.d.ts +13 -0
  48. package/esm/typings/src/book-components/_common/Tooltip/Tooltip.d.ts +47 -0
  49. package/esm/typings/src/book-components/_common/react-utils/classNames.d.ts +1 -1
  50. package/esm/typings/src/book-components/icons/AboutIcon.d.ts +9 -0
  51. package/esm/typings/src/book-components/icons/CloseIcon.d.ts +4 -8
  52. package/esm/typings/src/book-components/icons/DownloadIcon.d.ts +9 -0
  53. package/esm/typings/src/book-components/icons/ExitFullscreenIcon.d.ts +7 -0
  54. package/esm/typings/src/book-components/icons/FullscreenIcon.d.ts +7 -0
  55. package/esm/typings/src/book-components/icons/MenuIcon.d.ts +12 -0
  56. package/esm/typings/src/book-components/icons/MicIcon.d.ts +8 -0
  57. package/esm/typings/src/cli/cli-commands/_boilerplate.d.ts +2 -1
  58. package/esm/typings/src/cli/cli-commands/about.d.ts +3 -1
  59. package/esm/typings/src/cli/cli-commands/hello.d.ts +2 -1
  60. package/esm/typings/src/cli/cli-commands/list-models.d.ts +2 -1
  61. package/esm/typings/src/cli/cli-commands/list-scrapers.d.ts +2 -1
  62. package/esm/typings/src/cli/cli-commands/login.d.ts +2 -1
  63. package/esm/typings/src/cli/cli-commands/make.d.ts +2 -1
  64. package/esm/typings/src/cli/cli-commands/prettify.d.ts +2 -1
  65. package/esm/typings/src/cli/cli-commands/run.d.ts +2 -1
  66. package/esm/typings/src/cli/cli-commands/{start-server.d.ts → start-agents-server.d.ts} +3 -2
  67. package/esm/typings/src/cli/cli-commands/start-pipelines-server.d.ts +15 -0
  68. package/esm/typings/src/cli/cli-commands/test-command.d.ts +2 -1
  69. package/esm/typings/src/cli/common/$addGlobalOptionsToCommand.d.ts +2 -1
  70. package/esm/typings/src/collection/agent-collection/AgentCollection.d.ts +12 -0
  71. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +75 -0
  72. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabaseOptions.d.ts +10 -0
  73. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +154 -0
  74. package/esm/typings/src/collection/{PipelineCollection.d.ts → pipeline-collection/PipelineCollection.d.ts} +7 -3
  75. package/esm/typings/src/collection/{SimplePipelineCollection.d.ts → pipeline-collection/SimplePipelineCollection.d.ts} +5 -5
  76. package/esm/typings/src/collection/{constructors/createCollectionFromDirectory.d.ts → pipeline-collection/constructors/createPipelineCollectionFromDirectory.d.ts} +8 -11
  77. package/esm/typings/src/collection/pipeline-collection/constructors/createPipelineCollectionFromJson.d.ts +13 -0
  78. package/esm/typings/src/collection/{constructors/createCollectionFromPromise.d.ts → pipeline-collection/constructors/createPipelineCollectionFromPromise.d.ts} +6 -5
  79. package/esm/typings/src/collection/pipeline-collection/constructors/createPipelineCollectionFromPromise.test.d.ts +1 -0
  80. package/esm/typings/src/collection/{constructors/createCollectionFromUrl.d.ts → pipeline-collection/constructors/createPipelineCollectionFromUrl.d.ts} +3 -3
  81. package/esm/typings/src/collection/{constructors/createSubcollection.d.ts → pipeline-collection/constructors/createPipelineSubcollection.d.ts} +3 -3
  82. package/esm/typings/src/collection/pipeline-collection/pipelineCollectionToJson.d.ts +13 -0
  83. package/esm/typings/src/commands/_common/types/CommandParser.d.ts +4 -5
  84. package/esm/typings/src/{book-2.0/commitments → commitments}/ACTION/ACTION.d.ts +5 -1
  85. package/esm/typings/src/commitments/CLOSED/CLOSED.d.ts +35 -0
  86. package/esm/typings/src/commitments/COMPONENT/COMPONENT.d.ts +28 -0
  87. package/esm/typings/src/{book-2.0/commitments → commitments}/DELETE/DELETE.d.ts +5 -1
  88. package/esm/typings/src/{book-2.0/commitments → commitments}/FORMAT/FORMAT.d.ts +5 -1
  89. package/esm/typings/src/commitments/FROM/FROM.d.ts +34 -0
  90. package/esm/typings/src/{book-2.0/commitments → commitments}/GOAL/GOAL.d.ts +5 -1
  91. package/esm/typings/src/{book-2.0/commitments → commitments}/KNOWLEDGE/KNOWLEDGE.d.ts +5 -5
  92. package/esm/typings/src/commitments/LANGUAGE/LANGUAGE.d.ts +35 -0
  93. package/esm/typings/src/{book-2.0/commitments → commitments}/MEMORY/MEMORY.d.ts +5 -1
  94. package/esm/typings/src/commitments/MESSAGE/AgentMessageCommitmentDefinition.d.ts +32 -0
  95. package/esm/typings/src/commitments/MESSAGE/InitialMessageCommitmentDefinition.d.ts +32 -0
  96. package/esm/typings/src/{book-2.0/commitments → commitments}/MESSAGE/MESSAGE.d.ts +5 -1
  97. package/esm/typings/src/commitments/MESSAGE/UserMessageCommitmentDefinition.d.ts +32 -0
  98. package/esm/typings/src/{book-2.0/commitments → commitments}/META/META.d.ts +5 -1
  99. package/esm/typings/src/commitments/META_COLOR/META_COLOR.d.ts +48 -0
  100. package/esm/typings/src/commitments/META_FONT/META_FONT.d.ts +42 -0
  101. package/esm/typings/src/{book-2.0/commitments → commitments}/META_IMAGE/META_IMAGE.d.ts +5 -1
  102. package/esm/typings/src/{book-2.0/commitments → commitments}/META_LINK/META_LINK.d.ts +5 -1
  103. package/esm/typings/src/{book-2.0/commitments → commitments}/MODEL/MODEL.d.ts +5 -1
  104. package/esm/typings/src/{book-2.0/commitments → commitments}/NOTE/NOTE.d.ts +5 -1
  105. package/esm/typings/src/commitments/OPEN/OPEN.d.ts +35 -0
  106. package/esm/typings/src/{book-2.0/commitments → commitments}/PERSONA/PERSONA.d.ts +5 -1
  107. package/esm/typings/src/{book-2.0/commitments → commitments}/RULE/RULE.d.ts +5 -1
  108. package/esm/typings/src/{book-2.0/commitments → commitments}/SAMPLE/SAMPLE.d.ts +5 -1
  109. package/esm/typings/src/{book-2.0/commitments → commitments}/SCENARIO/SCENARIO.d.ts +5 -1
  110. package/esm/typings/src/{book-2.0/commitments → commitments}/STYLE/STYLE.d.ts +5 -1
  111. package/esm/typings/src/commitments/USE/USE.d.ts +53 -0
  112. package/esm/typings/src/commitments/USE_BROWSER/USE_BROWSER.d.ts +38 -0
  113. package/esm/typings/src/commitments/USE_BROWSER/USE_BROWSER.test.d.ts +1 -0
  114. package/esm/typings/src/commitments/USE_MCP/USE_MCP.d.ts +37 -0
  115. package/esm/typings/src/commitments/USE_SEARCH_ENGINE/USE_SEARCH_ENGINE.d.ts +38 -0
  116. package/esm/typings/src/{book-2.0/commitments → commitments}/_base/BaseCommitmentDefinition.d.ts +8 -2
  117. package/esm/typings/src/{book-2.0/commitments → commitments}/_base/CommitmentDefinition.d.ts +6 -1
  118. package/esm/typings/src/{book-2.0/commitments → commitments}/_base/NotYetImplementedCommitmentDefinition.d.ts +5 -1
  119. package/esm/typings/src/{book-2.0/commitments → commitments}/_base/createEmptyAgentModelRequirements.d.ts +1 -1
  120. package/esm/typings/src/commitments/index.d.ts +93 -0
  121. package/esm/typings/src/config.d.ts +24 -3
  122. package/esm/typings/src/conversion/validation/validatePipeline.d.ts +2 -0
  123. package/esm/typings/src/errors/0-index.d.ts +6 -0
  124. package/esm/typings/src/errors/DatabaseError.d.ts +12 -0
  125. package/esm/typings/src/errors/NotAllowed.d.ts +9 -0
  126. package/esm/typings/src/errors/WrappedError.d.ts +2 -2
  127. package/esm/typings/src/execution/AvailableModel.d.ts +1 -0
  128. package/esm/typings/src/execution/Executables.d.ts +3 -0
  129. package/esm/typings/src/execution/ExecutionTask.d.ts +12 -3
  130. package/esm/typings/src/execution/ExecutionTools.d.ts +5 -0
  131. package/esm/typings/src/execution/FilesystemTools.d.ts +1 -1
  132. package/esm/typings/src/execution/LlmExecutionTools.d.ts +21 -1
  133. package/esm/typings/src/execution/createPipelineExecutor/10-executePipeline.d.ts +5 -0
  134. package/esm/typings/src/execution/createPipelineExecutor/20-executeTask.d.ts +5 -0
  135. package/esm/typings/src/execution/createPipelineExecutor/30-executeFormatSubvalues.d.ts +5 -0
  136. package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempts.d.ts +5 -0
  137. package/esm/typings/src/execution/utils/usage-constants.d.ts +4 -124
  138. package/esm/typings/src/execution/utils/validatePromptResult.d.ts +2 -0
  139. package/esm/typings/src/high-level-abstractions/_common/HighLevelAbstraction.d.ts +2 -1
  140. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForWizardOrCli.d.ts +2 -2
  141. package/esm/typings/src/llm-providers/_common/register/$registeredLlmToolsMessage.d.ts +2 -1
  142. package/esm/typings/src/llm-providers/_common/register/LlmToolsMetadata.d.ts +1 -1
  143. package/esm/typings/src/llm-providers/_common/utils/assertUniqueModels.d.ts +12 -0
  144. package/esm/typings/src/llm-providers/_multiple/getSingleLlmExecutionTools.d.ts +1 -0
  145. package/esm/typings/src/llm-providers/_multiple/joinLlmExecutionTools.d.ts +1 -0
  146. package/esm/typings/src/llm-providers/agent/Agent.d.ts +70 -0
  147. package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +26 -4
  148. package/esm/typings/src/llm-providers/agent/AgentOptions.d.ts +19 -0
  149. package/esm/typings/src/llm-providers/agent/CreateAgentLlmExecutionToolsOptions.d.ts +17 -0
  150. package/esm/typings/src/llm-providers/agent/RemoteAgent.d.ts +50 -0
  151. package/esm/typings/src/llm-providers/agent/RemoteAgentOptions.d.ts +11 -0
  152. package/esm/typings/src/llm-providers/agent/createAgentLlmExecutionTools.d.ts +1 -19
  153. package/esm/typings/src/llm-providers/anthropic-claude/anthropic-claude-models.d.ts +1 -1
  154. package/esm/typings/src/llm-providers/google/google-models.d.ts +1 -1
  155. package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionTools.d.ts +60 -2
  156. package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionToolsOptions.d.ts +7 -1
  157. package/esm/typings/src/llm-providers/openai/openai-models.d.ts +1 -1
  158. package/esm/typings/src/llm-providers/openai/openai-models.test.d.ts +4 -0
  159. package/esm/typings/src/other/templates/getTemplatesPipelineCollection.d.ts +1 -1
  160. package/esm/typings/src/pipeline/validatePipelineString.d.ts +2 -0
  161. package/esm/typings/src/playground/permanent/_boilerplate.d.ts +5 -0
  162. package/esm/typings/src/playground/permanent/agent-with-browser-playground.d.ts +5 -0
  163. package/esm/typings/src/prepare/PrepareAndScrapeOptions.d.ts +1 -0
  164. package/esm/typings/src/remote-server/startAgentServer.d.ts +26 -0
  165. package/esm/typings/src/remote-server/startRemoteServer.d.ts +4 -1
  166. package/esm/typings/src/remote-server/types/RemoteServerOptions.d.ts +3 -8
  167. package/esm/typings/src/scrapers/_boilerplate/createBoilerplateScraper.d.ts +1 -12
  168. package/esm/typings/src/scrapers/_boilerplate/register-metadata.d.ts +1 -9
  169. package/esm/typings/src/scrapers/document/createDocumentScraper.d.ts +1 -12
  170. package/esm/typings/src/scrapers/document/register-metadata.d.ts +1 -9
  171. package/esm/typings/src/scrapers/document-legacy/createLegacyDocumentScraper.d.ts +1 -12
  172. package/esm/typings/src/scrapers/document-legacy/register-metadata.d.ts +1 -9
  173. package/esm/typings/src/scrapers/markdown/createMarkdownScraper.d.ts +1 -12
  174. package/esm/typings/src/scrapers/markdown/register-metadata.d.ts +1 -9
  175. package/esm/typings/src/scrapers/markitdown/createMarkitdownScraper.d.ts +1 -12
  176. package/esm/typings/src/scrapers/markitdown/register-metadata.d.ts +1 -9
  177. package/esm/typings/src/scrapers/pdf/createPdfScraper.d.ts +1 -12
  178. package/esm/typings/src/scrapers/pdf/register-metadata.d.ts +1 -9
  179. package/esm/typings/src/scrapers/website/createWebsiteScraper.d.ts +1 -12
  180. package/esm/typings/src/scrapers/website/register-metadata.d.ts +1 -9
  181. package/esm/typings/src/storage/_common/PromptbookStorage.d.ts +1 -0
  182. package/esm/typings/src/storage/env-storage/$EnvStorage.d.ts +2 -1
  183. package/esm/typings/src/transpilers/_common/BookTranspiler.d.ts +33 -0
  184. package/esm/typings/src/transpilers/_common/BookTranspilerOptions.d.ts +18 -0
  185. package/esm/typings/src/transpilers/_common/register/$bookTranspilersRegister.d.ts +15 -0
  186. package/esm/typings/src/transpilers/formatted-book-in-markdown/FormattedBookInMarkdownTranspiler.d.ts +16 -0
  187. package/esm/typings/src/transpilers/formatted-book-in-markdown/register.d.ts +15 -0
  188. package/esm/typings/src/transpilers/openai-sdk/OpenAiSdkTranspiler.d.ts +16 -0
  189. package/esm/typings/src/transpilers/openai-sdk/OpenAiSdkTranspiler.test.d.ts +1 -0
  190. package/esm/typings/src/transpilers/openai-sdk/playground/playground.d.ts +5 -0
  191. package/esm/typings/src/transpilers/openai-sdk/register.d.ts +15 -0
  192. package/esm/typings/src/types/LlmCall.d.ts +20 -0
  193. package/esm/typings/src/types/Updatable.d.ts +19 -0
  194. package/esm/typings/src/types/typeAliases.d.ts +32 -2
  195. package/esm/typings/src/utils/color/$randomColor.d.ts +1 -0
  196. package/esm/typings/src/utils/color/Color.d.ts +15 -0
  197. package/esm/typings/src/utils/color/Color.test.d.ts +1 -0
  198. package/esm/typings/src/utils/color/css-colors.d.ts +1 -0
  199. package/esm/typings/src/utils/color/internal-utils/checkChannelValue.d.ts +0 -3
  200. package/esm/typings/src/utils/color/operators/darken.d.ts +1 -1
  201. package/esm/typings/src/utils/color/operators/grayscale.d.ts +1 -1
  202. package/esm/typings/src/utils/color/operators/lighten.d.ts +1 -1
  203. package/esm/typings/src/utils/color/operators/mixWithColor.d.ts +1 -1
  204. package/esm/typings/src/utils/color/operators/saturate.d.ts +1 -1
  205. package/esm/typings/src/utils/environment/$detectRuntimeEnvironment.d.ts +16 -0
  206. package/esm/typings/src/utils/environment/$getGlobalScope.d.ts +2 -2
  207. package/esm/typings/src/utils/execCommand/$execCommand.d.ts +2 -1
  208. package/esm/typings/src/utils/execCommand/$execCommands.d.ts +2 -1
  209. package/esm/typings/src/utils/files/$induceBookDownload.d.ts +13 -0
  210. package/esm/typings/src/utils/files/$induceFileDownload.d.ts +13 -0
  211. package/esm/typings/src/utils/files/ObjectUrl.d.ts +46 -0
  212. package/esm/typings/src/utils/files/listAllFiles.d.ts +2 -3
  213. package/esm/typings/src/utils/misc/aboutPromptbookInformation.d.ts +27 -0
  214. package/esm/typings/src/utils/misc/computeHash.d.ts +11 -0
  215. package/esm/typings/src/utils/misc/computeHash.test.d.ts +1 -0
  216. package/esm/typings/src/utils/misc/injectCssModuleIntoShadowRoot.d.ts +1 -0
  217. package/esm/typings/src/utils/misc/xAboutPromptbookInformation.d.ts +13 -0
  218. package/esm/typings/src/utils/normalization/normalize-to-kebab-case.d.ts +2 -0
  219. package/esm/typings/src/utils/normalization/normalizeMessageText.d.ts +9 -0
  220. package/esm/typings/src/utils/normalization/normalizeMessageText.test.d.ts +1 -0
  221. package/esm/typings/src/utils/normalization/normalizeTo_PascalCase.d.ts +3 -0
  222. package/esm/typings/src/utils/normalization/normalizeTo_camelCase.d.ts +2 -0
  223. package/esm/typings/src/utils/normalization/titleToName.d.ts +2 -0
  224. package/esm/typings/src/utils/organization/$sideEffect.d.ts +2 -2
  225. package/esm/typings/src/utils/organization/$side_effect.d.ts +7 -0
  226. package/esm/typings/src/utils/organization/TODO_USE.d.ts +2 -2
  227. package/esm/typings/src/utils/organization/keepUnused.d.ts +2 -2
  228. package/esm/typings/src/utils/organization/preserve.d.ts +3 -3
  229. package/esm/typings/src/utils/organization/really_any.d.ts +7 -0
  230. package/esm/typings/src/utils/random/$generateBookBoilerplate.d.ts +25 -0
  231. package/esm/typings/src/utils/random/$randomAgentPersona.d.ts +9 -0
  232. package/esm/typings/src/utils/random/$randomFullnameWithColor.d.ts +13 -0
  233. package/esm/typings/src/utils/random/$randomItem.d.ts +9 -0
  234. package/esm/typings/src/utils/random/$randomSeed.d.ts +3 -0
  235. package/esm/typings/src/utils/random/$randomToken.d.ts +2 -0
  236. package/esm/typings/src/utils/serialization/$deepFreeze.d.ts +2 -1
  237. package/esm/typings/src/utils/serialization/asSerializable.d.ts +2 -2
  238. package/esm/typings/src/utils/serialization/serializeToPromptbookJavascript.d.ts +2 -2
  239. package/esm/typings/src/utils/validators/parameterName/validateParameterName.d.ts +2 -0
  240. package/esm/typings/src/version.d.ts +1 -1
  241. package/esm/typings/src/wizard/$getCompiledBook.d.ts +1 -2
  242. package/package.json +6 -4
  243. package/umd/index.umd.js +4509 -119
  244. package/umd/index.umd.js.map +1 -1
  245. package/esm/typings/src/book-2.0/commitments/index.d.ts +0 -60
  246. package/esm/typings/src/book-components/BookEditor/BookEditorInner.d.ts +0 -5
  247. package/esm/typings/src/book-components/BookEditor/config.d.ts +0 -10
  248. package/esm/typings/src/book-components/Chat/utils/renderMarkdown.d.ts +0 -21
  249. package/esm/typings/src/collection/collectionToJson.d.ts +0 -13
  250. package/esm/typings/src/collection/constructors/createCollectionFromJson.d.ts +0 -13
  251. /package/esm/typings/src/{book-components/Chat/utils/renderMarkdown.test.d.ts → book-2.0/agent-source/computeAgentHash.test.d.ts} +0 -0
  252. /package/esm/typings/src/{collection/constructors/createCollectionFromDirectory.test.d.ts → book-2.0/agent-source/normalizeAgentName.test.d.ts} +0 -0
  253. /package/esm/typings/src/{collection/constructors/createCollectionFromJson.test.d.ts → book-components/Chat/AgentChat/AgentChat.test.d.ts} +0 -0
  254. /package/esm/typings/src/collection/{constructors/createCollectionFromPromise.test.d.ts → pipeline-collection/constructors/createPipelineCollectionFromDirectory.test.d.ts} +0 -0
  255. /package/esm/typings/src/{commands/_common/parseCommand.test.d.ts → collection/pipeline-collection/constructors/createPipelineCollectionFromJson.test.d.ts} +0 -0
  256. /package/esm/typings/src/collection/{collectionToJson.test.d.ts → pipeline-collection/pipelineCollectionToJson.test.d.ts} +0 -0
  257. /package/esm/typings/src/{book-2.0/commitments → commitments}/_base/BookCommitment.d.ts +0 -0
  258. /package/esm/typings/src/{book-2.0/commitments → commitments}/_base/ParsedCommitment.d.ts +0 -0
package/umd/index.umd.js CHANGED
@@ -1,12 +1,13 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('spacetrim'), require('crypto'), require('openai/core')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'spacetrim', 'crypto', 'openai/core'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-browser"] = {}, global.spaceTrim, global.crypto, global.core));
5
- })(this, (function (exports, spaceTrim, crypto, core) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('spacetrim'), require('crypto'), require('crypto-js'), require('crypto-js/enc-hex'), require('path'), require('destroyable')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'spacetrim', 'crypto', 'crypto-js', 'crypto-js/enc-hex', 'path', 'destroyable'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-browser"] = {}, global.spaceTrim$1, global.crypto, global.cryptoJs, global.hexEncoder, global.path, global.destroyable));
5
+ })(this, (function (exports, spaceTrim$1, crypto, cryptoJs, hexEncoder, path, destroyable) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
9
- var spaceTrim__default = /*#__PURE__*/_interopDefaultLegacy(spaceTrim);
9
+ var spaceTrim__default = /*#__PURE__*/_interopDefaultLegacy(spaceTrim$1);
10
+ var hexEncoder__default = /*#__PURE__*/_interopDefaultLegacy(hexEncoder);
10
11
 
11
12
  // ⚠️ WARNING: This code has been generated so that any manual changes will be overwritten
12
13
  /**
@@ -15,14 +16,14 @@
15
16
  * @generated
16
17
  * @see https://github.com/webgptorg/book
17
18
  */
18
- const BOOK_LANGUAGE_VERSION = '1.0.0';
19
+ const BOOK_LANGUAGE_VERSION = '2.0.0';
19
20
  /**
20
21
  * The version of the Promptbook engine
21
22
  *
22
23
  * @generated
23
24
  * @see https://github.com/webgptorg/promptbook
24
25
  */
25
- const PROMPTBOOK_ENGINE_VERSION = '0.103.0-1';
26
+ const PROMPTBOOK_ENGINE_VERSION = '0.103.0-100';
26
27
  /**
27
28
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
28
29
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -31,6 +32,7 @@
31
32
  /**
32
33
  * Generates random token
33
34
  *
35
+ * Note: `$` is used to indicate that this function is not a pure function - it is not deterministic
34
36
  * Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
35
37
  *
36
38
  * @private internal helper function
@@ -40,6 +42,7 @@
40
42
  return crypto.randomBytes(randomness).toString('hex');
41
43
  }
42
44
  /**
45
+ * TODO: [🤶] Maybe export through `@promptbook/utils` or `@promptbook/random` package
43
46
  * TODO: Maybe use nanoid instead https://github.com/ai/nanoid
44
47
  */
45
48
 
@@ -78,13 +81,13 @@
78
81
  * Trigger window.prompt dialog
79
82
  */
80
83
  async promptDialog(options) {
81
- const answer = window.prompt(spaceTrim.spaceTrim((block) => `
84
+ const answer = window.prompt(spaceTrim$1.spaceTrim((block) => `
82
85
  ${block(options.promptTitle)}
83
86
 
84
87
  ${block(options.promptMessage)}
85
88
  `));
86
89
  if (this.options.isVerbose) {
87
- console.info(spaceTrim.spaceTrim((block) => `
90
+ console.info(spaceTrim$1.spaceTrim((block) => `
88
91
  📖 ${block(options.promptTitle)}
89
92
  👤 ${block(answer || '🚫 User cancelled prompt')}
90
93
  `));
@@ -152,6 +155,17 @@
152
155
  * TODO: [🎺]
153
156
  */
154
157
 
158
+ /**
159
+ * Trims string from all 4 sides
160
+ *
161
+ * Note: This is a re-exported function from the `spacetrim` package which is
162
+ * Developed by same author @hejny as this package
163
+ *
164
+ * @public exported from `@promptbook/utils`
165
+ * @see https://github.com/hejny/spacetrim#usage
166
+ */
167
+ const spaceTrim = spaceTrim$1.spaceTrim;
168
+
155
169
  /**
156
170
  * @private util of `@promptbook/color`
157
171
  * @de
@@ -200,6 +214,7 @@
200
214
  * @public exported from `@promptbook/color`
201
215
  */
202
216
  const CSS_COLORS = {
217
+ promptbook: '#79EAFD',
203
218
  transparent: 'rgba(0,0,0,0)',
204
219
  aliceblue: '#f0f8ff',
205
220
  antiquewhite: '#faebd7',
@@ -381,9 +396,6 @@
381
396
  throw new Error(`${channelName} channel is greater than 255, it is ${value}`);
382
397
  }
383
398
  }
384
- /**
385
- * TODO: [🧠][🚓] Is/which combination it better to use asserts/check, validate or is utility function?
386
- */
387
399
 
388
400
  /**
389
401
  * Color object represents an RGB color with alpha channel
@@ -418,6 +430,28 @@
418
430
  throw new Error(`Can not create color from given object`);
419
431
  }
420
432
  }
433
+ /**
434
+ * Creates a new Color instance from miscellaneous formats
435
+ * It just does not throw error when it fails, it returns PROMPTBOOK_COLOR instead
436
+ *
437
+ * @param color
438
+ * @returns Color object
439
+ */
440
+ static fromSafe(color) {
441
+ try {
442
+ return Color.from(color);
443
+ }
444
+ catch (error) {
445
+ // <- Note: Can not use `assertsError(error)` here because it causes circular dependency
446
+ console.warn(spaceTrim((block) => `
447
+ Color.fromSafe error:
448
+ ${block(error.message)}
449
+
450
+ Returning default PROMPTBOOK_COLOR.
451
+ `));
452
+ return Color.fromString('promptbook');
453
+ }
454
+ }
421
455
  /**
422
456
  * Creates a new Color instance from miscellaneous string formats
423
457
  *
@@ -485,6 +519,9 @@
485
519
  if (hex.length === 3) {
486
520
  return Color.fromHex3(hex);
487
521
  }
522
+ if (hex.length === 4) {
523
+ return Color.fromHex4(hex);
524
+ }
488
525
  if (hex.length === 6) {
489
526
  return Color.fromHex6(hex);
490
527
  }
@@ -505,6 +542,19 @@
505
542
  const b = parseInt(hex.substr(2, 1), 16) * 16;
506
543
  return take(new Color(r, g, b));
507
544
  }
545
+ /**
546
+ * Creates a new Color instance from color in hex format with 4 digits (with alpha channel)
547
+ *
548
+ * @param color in hex for example `09df`
549
+ * @returns Color object
550
+ */
551
+ static fromHex4(hex) {
552
+ const r = parseInt(hex.substr(0, 1), 16) * 16;
553
+ const g = parseInt(hex.substr(1, 1), 16) * 16;
554
+ const b = parseInt(hex.substr(2, 1), 16) * 16;
555
+ const a = parseInt(hex.substr(3, 1), 16) * 16;
556
+ return take(new Color(r, g, b, a));
557
+ }
508
558
  /**
509
559
  * Creates a new Color instance from color in hex format with 6 color digits (without alpha channel)
510
560
  *
@@ -695,7 +745,8 @@
695
745
  * @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
696
746
  */
697
747
  static isHexColorString(value) {
698
- return typeof value === 'string' && /^#(?:[0-9a-fA-F]{3}){1,2}$/.test(value);
748
+ return (typeof value === 'string' &&
749
+ /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value));
699
750
  }
700
751
  /**
701
752
  * Creates new Color object
@@ -810,6 +861,23 @@
810
861
  * TODO: Maybe connect with textures
811
862
  */
812
863
 
864
+ /**
865
+ * Makes color transformer which returns a grayscale version of the color
866
+ *
867
+ * @param amount from 0 to 1
868
+ *
869
+ * @public exported from `@promptbook/color`
870
+ */
871
+ function grayscale(amount) {
872
+ return ({ red, green, blue, alpha }) => {
873
+ const average = (red + green + blue) / 3;
874
+ red = Math.round(average * amount + red * (1 - amount));
875
+ green = Math.round(average * amount + green * (1 - amount));
876
+ blue = Math.round(average * amount + blue * (1 - amount));
877
+ return Color.fromValues(red, green, blue, alpha);
878
+ };
879
+ }
880
+
813
881
  /**
814
882
  * Converts HSL values to RGB values
815
883
  *
@@ -925,102 +993,6 @@
925
993
  * TODO: Maybe implement by mix+hsl
926
994
  */
927
995
 
928
- /**
929
- * Calculates distance between two colors
930
- *
931
- * @param color1 first color
932
- * @param color2 second color
933
- *
934
- * Note: This function is inefficient. Use colorDistanceSquared instead if possible.
935
- *
936
- * @public exported from `@promptbook/color`
937
- */
938
- /**
939
- * Calculates distance between two colors without square root
940
- *
941
- * @param color1 first color
942
- * @param color2 second color
943
- *
944
- * @public exported from `@promptbook/color`
945
- */
946
- function colorDistanceSquared(color1, color2) {
947
- const rmean = (color1.red + color2.red) / 2;
948
- const r = color1.red - color2.red;
949
- const g = color1.green - color2.green;
950
- const b = color1.blue - color2.blue;
951
- const weightR = 2 + rmean / 256;
952
- const weightG = 4.0;
953
- const weightB = 2 + (255 - rmean) / 256;
954
- const distance = weightR * r * r + weightG * g * g + weightB * b * b;
955
- return distance;
956
- }
957
-
958
- /**
959
- * Makes color transformer which finds the nearest color from the given list
960
- *
961
- * @param colors array of colors to choose from
962
- *
963
- * @public exported from `@promptbook/color`
964
- */
965
- function nearest(...colors) {
966
- return (color) => {
967
- const distances = colors.map((c) => colorDistanceSquared(c, color));
968
- const minDistance = Math.min(...distances);
969
- const minIndex = distances.indexOf(minDistance);
970
- const nearestColor = colors[minIndex];
971
- return nearestColor;
972
- };
973
- }
974
-
975
- /**
976
- * Color transformer which returns the negative color
977
- *
978
- * @public exported from `@promptbook/color`
979
- */
980
- function negative(color) {
981
- const r = 255 - color.red;
982
- const g = 255 - color.green;
983
- const b = 255 - color.blue;
984
- return Color.fromValues(r, g, b, color.alpha);
985
- }
986
-
987
- /**
988
- * Makes color transformer which finds the furthest color from the given list
989
- *
990
- * @param colors array of colors to choose from
991
- *
992
- * @public exported from `@promptbook/color`
993
- */
994
- function furthest(...colors) {
995
- return (color) => {
996
- const furthestColor = negative(nearest(...colors.map(negative))(color));
997
- return furthestColor;
998
- };
999
- }
1000
- /**
1001
- * Makes color transformer which finds the best text color (black or white) for the given background color
1002
- *
1003
- * @public exported from `@promptbook/color`
1004
- */
1005
- furthest(Color.get('white'), Color.from('black'));
1006
-
1007
- /**
1008
- * Makes color transformer which returns a grayscale version of the color
1009
- *
1010
- * @param amount from 0 to 1
1011
- *
1012
- * @public exported from `@promptbook/color`
1013
- */
1014
- function grayscale(amount) {
1015
- return ({ red, green, blue, alpha }) => {
1016
- const average = (red + green + blue) / 3;
1017
- red = Math.round(average * amount + red * (1 - amount));
1018
- green = Math.round(average * amount + green * (1 - amount));
1019
- blue = Math.round(average * amount + blue * (1 - amount));
1020
- return Color.fromValues(red, green, blue, alpha);
1021
- };
1022
- }
1023
-
1024
996
  /**
1025
997
  * Makes color transformer which saturate the given color
1026
998
  *
@@ -1069,16 +1041,32 @@
1069
1041
  *
1070
1042
  * @public exported from `@promptbook/core`
1071
1043
  */
1072
- const PROMPTBOOK_COLOR = Color.fromHex('#79EAFD');
1073
- // <- TODO: [🧠] Using `Color` here increases the package size approx 3kb, maybe remove it
1044
+ const PROMPTBOOK_COLOR = Color.fromString('promptbook');
1045
+ // <- TODO: [🧠][🈵] Using `Color` here increases the package size approx 3kb, maybe remove it
1046
+ /**
1047
+ * Colors for syntax highlighting in the `<BookEditor/>`
1048
+ *
1049
+ * TODO: [🗽] Unite branding and make single place for it
1050
+ *
1051
+ * @public exported from `@promptbook/core`
1052
+ */
1053
+ ({
1054
+ TITLE: Color.fromHex('#244EA8'),
1055
+ LINE: Color.fromHex('#eeeeee'),
1056
+ SEPARATOR: Color.fromHex('#cccccc'),
1057
+ COMMITMENT: Color.fromHex('#DA0F78'),
1058
+ PARAMETER: Color.fromHex('#8e44ad'),
1059
+ });
1060
+ // <- TODO: [🧠][🈵] Using `Color` here increases the package size approx 3kb, maybe remove it
1074
1061
  /**
1075
- * Dark color of the Promptbook
1062
+ * Chat color of the Promptbook (in chat)
1076
1063
  *
1077
1064
  * TODO: [🗽] Unite branding and make single place for it
1078
1065
  *
1079
1066
  * @public exported from `@promptbook/core`
1080
1067
  */
1081
1068
  PROMPTBOOK_COLOR.then(lighten(0.1)).then(saturate(0.9)).then(grayscale(0.9));
1069
+ // <- TODO: [🧠][🈵] Using `Color` and `lighten`, `saturate`,... here increases the package size approx 3kb, maybe remove it
1082
1070
  /**
1083
1071
  * Color of the user (in chat)
1084
1072
  *
@@ -1094,6 +1082,27 @@
1094
1082
  * @private within the repository - too low-level in comparison with other `MAX_...`
1095
1083
  */
1096
1084
  const LOOP_LIMIT = 1000;
1085
+ /**
1086
+ * Strings to represent various values in the context of parameter values
1087
+ *
1088
+ * @public exported from `@promptbook/utils`
1089
+ */
1090
+ const VALUE_STRINGS = {
1091
+ empty: '(nothing; empty string)',
1092
+ null: '(no value; null)',
1093
+ undefined: '(unknown value; undefined)',
1094
+ nan: '(not a number; NaN)',
1095
+ infinity: '(infinity; ∞)',
1096
+ negativeInfinity: '(negative infinity; -∞)',
1097
+ unserializable: '(unserializable value)',
1098
+ circular: '(circular JSON)',
1099
+ };
1100
+ /**
1101
+ * Small number limit
1102
+ *
1103
+ * @public exported from `@promptbook/utils`
1104
+ */
1105
+ const SMALL_NUMBER = 0.001;
1097
1106
  // <- TODO: [🧜‍♂️]
1098
1107
  /**
1099
1108
  * Default settings for parsing and generating CSV files in Promptbook.
@@ -1125,7 +1134,7 @@
1125
1134
  */
1126
1135
  class NotYetImplementedError extends Error {
1127
1136
  constructor(message) {
1128
- super(spaceTrim.spaceTrim((block) => `
1137
+ super(spaceTrim$1.spaceTrim((block) => `
1129
1138
  ${block(message)}
1130
1139
 
1131
1140
  Note: This feature is not implemented yet but it will be soon.
@@ -1192,7 +1201,7 @@
1192
1201
  */
1193
1202
  class UnexpectedError extends Error {
1194
1203
  constructor(message) {
1195
- super(spaceTrim.spaceTrim((block) => `
1204
+ super(spaceTrim$1.spaceTrim((block) => `
1196
1205
  ${block(message)}
1197
1206
 
1198
1207
  Note: This error should not happen.
@@ -1444,7 +1453,7 @@
1444
1453
  * @public exported from `@promptbook/browser`
1445
1454
  */
1446
1455
  function getIndexedDbStorage(options) {
1447
- if (!core.isRunningInBrowser()) {
1456
+ if (!$isRunningInBrowser()) {
1448
1457
  throw new EnvironmentMismatchError(`You can get IndexedDB storage only in browser environment`);
1449
1458
  }
1450
1459
  const { databaseName, storeName } = options;
@@ -1547,7 +1556,7 @@
1547
1556
  constructor(whatWasThrown) {
1548
1557
  const tag = `[🤮]`;
1549
1558
  console.error(tag, whatWasThrown);
1550
- super(spaceTrim.spaceTrim(`
1559
+ super(spaceTrim$1.spaceTrim(`
1551
1560
  Non-Error object was thrown
1552
1561
 
1553
1562
  Note: Look for ${tag} in the console for more details
@@ -1740,7 +1749,7 @@
1740
1749
  TODO: [🧠] Is there a better implementation?
1741
1750
  > const propertyNames = Object.getOwnPropertyNames(objectValue);
1742
1751
  > for (const propertyName of propertyNames) {
1743
- > const value = (objectValue as really_any)[propertyName];
1752
+ > const value = (objectValue as chococake)[propertyName];
1744
1753
  > if (value && typeof value === 'object') {
1745
1754
  > deepClone(value);
1746
1755
  > }
@@ -1929,7 +1938,7 @@
1929
1938
  * @public exported from `@promptbook/browser`
1930
1939
  */
1931
1940
  function getLocalStorage() {
1932
- if (!core.isRunningInBrowser()) {
1941
+ if (!$isRunningInBrowser()) {
1933
1942
  throw new EnvironmentMismatchError(`You can get localStorage works only in browser environment`);
1934
1943
  }
1935
1944
  if (promptbookLocalStorage) {
@@ -1954,7 +1963,7 @@
1954
1963
  * @public exported from `@promptbook/browser`
1955
1964
  */
1956
1965
  function getSessionStorage() {
1957
- if (!core.isRunningInBrowser()) {
1966
+ if (!$isRunningInBrowser()) {
1958
1967
  throw new EnvironmentMismatchError(`You can get sessionStorage works only in browser environment`);
1959
1968
  }
1960
1969
  if (promptbookSessionStorage) {
@@ -1967,8 +1976,4389 @@
1967
1976
  * Note: [🔵] Code in this file should never be published outside of `@promptbook/browser`
1968
1977
  */
1969
1978
 
1979
+ /**
1980
+ * Normalizes a given text to camelCase format.
1981
+ *
1982
+ * Note: [🔂] This function is idempotent.
1983
+ *
1984
+ * @param text The text to be normalized.
1985
+ * @param _isFirstLetterCapital Whether the first letter should be capitalized.
1986
+ * @returns The camelCase formatted string.
1987
+ * @example 'helloWorld'
1988
+ * @example 'iLovePromptbook'
1989
+ * @public exported from `@promptbook/utils`
1990
+ */
1991
+ function normalizeTo_camelCase(text, _isFirstLetterCapital = false) {
1992
+ let charType;
1993
+ let lastCharType = null;
1994
+ let normalizedName = '';
1995
+ for (const char of text) {
1996
+ let normalizedChar;
1997
+ if (/^[a-z]$/.test(char)) {
1998
+ charType = 'LOWERCASE';
1999
+ normalizedChar = char;
2000
+ }
2001
+ else if (/^[A-Z]$/.test(char)) {
2002
+ charType = 'UPPERCASE';
2003
+ normalizedChar = char.toLowerCase();
2004
+ }
2005
+ else if (/^[0-9]$/.test(char)) {
2006
+ charType = 'NUMBER';
2007
+ normalizedChar = char;
2008
+ }
2009
+ else {
2010
+ charType = 'OTHER';
2011
+ normalizedChar = '';
2012
+ }
2013
+ if (!lastCharType) {
2014
+ if (_isFirstLetterCapital) {
2015
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
2016
+ }
2017
+ }
2018
+ else if (charType !== lastCharType &&
2019
+ !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
2020
+ !(lastCharType === 'NUMBER') &&
2021
+ !(charType === 'NUMBER')) {
2022
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
2023
+ }
2024
+ normalizedName += normalizedChar;
2025
+ lastCharType = charType;
2026
+ }
2027
+ return normalizedName;
2028
+ }
2029
+ /**
2030
+ * TODO: [🌺] Use some intermediate util splitWords
2031
+ */
2032
+
2033
+ /**
2034
+ * Generates a gravatar URL based on agent name for fallback avatar
2035
+ *
2036
+ * @param agentName The agent name to generate avatar for
2037
+ * @returns Gravatar URL
2038
+ *
2039
+ * @private - [🤹] The fact that profile image is Gravatar is just implementation detail which should be hidden for consumer
2040
+ */
2041
+ function generateGravatarUrl(agentName) {
2042
+ // Use a default name if none provided
2043
+ const safeName = agentName || 'Anonymous Agent';
2044
+ // Create a simple hash from the name for consistent avatar
2045
+ let hash = 0;
2046
+ for (let i = 0; i < safeName.length; i++) {
2047
+ const char = safeName.charCodeAt(i);
2048
+ hash = (hash << 5) - hash + char;
2049
+ hash = hash & hash; // Convert to 32bit integer
2050
+ }
2051
+ const avatarId = Math.abs(hash).toString();
2052
+ return `https://www.gravatar.com/avatar/${avatarId}?default=robohash&size=200&rating=x`;
2053
+ }
2054
+
2055
+ /**
2056
+ * Generates an image for the agent to use as profile image
2057
+ *
2058
+ * @param agentName The agent name to generate avatar for
2059
+ * @returns The placeholder profile image URL for the agent
2060
+ *
2061
+ * @public exported from `@promptbook/core`
2062
+ */
2063
+ function generatePlaceholderAgentProfileImageUrl(agentName) {
2064
+ // Note: [🤹] The fact that profile image is Gravatar is just implementation detail which should be hidden for consumer
2065
+ return generateGravatarUrl(agentName);
2066
+ }
2067
+ /**
2068
+ * TODO: [🤹] Figure out best placeholder image generator https://i.pravatar.cc/1000?u=568
2069
+ */
2070
+
2071
+ /**
2072
+ * Format either small or big number
2073
+ *
2074
+ * @public exported from `@promptbook/utils`
2075
+ */
2076
+ function numberToString(value) {
2077
+ if (value === 0) {
2078
+ return '0';
2079
+ }
2080
+ else if (Number.isNaN(value)) {
2081
+ return VALUE_STRINGS.nan;
2082
+ }
2083
+ else if (value === Infinity) {
2084
+ return VALUE_STRINGS.infinity;
2085
+ }
2086
+ else if (value === -Infinity) {
2087
+ return VALUE_STRINGS.negativeInfinity;
2088
+ }
2089
+ for (let exponent = 0; exponent < 15; exponent++) {
2090
+ const factor = 10 ** exponent;
2091
+ const valueRounded = Math.round(value * factor) / factor;
2092
+ if (Math.abs(value - valueRounded) / value < SMALL_NUMBER) {
2093
+ return valueRounded.toFixed(exponent);
2094
+ }
2095
+ }
2096
+ return value.toString();
2097
+ }
2098
+
2099
+ /**
2100
+ * Function `valueToString` will convert the given value to string
2101
+ * This is useful and used in the `templateParameters` function
2102
+ *
2103
+ * Note: This function is not just calling `toString` method
2104
+ * It's more complex and can handle this conversion specifically for LLM models
2105
+ * See `VALUE_STRINGS`
2106
+ *
2107
+ * Note: There are 2 similar functions
2108
+ * - `valueToString` converts value to string for LLM models as human-readable string
2109
+ * - `asSerializable` converts value to string to preserve full information to be able to convert it back
2110
+ *
2111
+ * @public exported from `@promptbook/utils`
2112
+ */
2113
+ function valueToString(value) {
2114
+ try {
2115
+ if (value === '') {
2116
+ return VALUE_STRINGS.empty;
2117
+ }
2118
+ else if (value === null) {
2119
+ return VALUE_STRINGS.null;
2120
+ }
2121
+ else if (value === undefined) {
2122
+ return VALUE_STRINGS.undefined;
2123
+ }
2124
+ else if (typeof value === 'string') {
2125
+ return value;
2126
+ }
2127
+ else if (typeof value === 'number') {
2128
+ return numberToString(value);
2129
+ }
2130
+ else if (value instanceof Date) {
2131
+ return value.toISOString();
2132
+ }
2133
+ else {
2134
+ try {
2135
+ return JSON.stringify(value);
2136
+ }
2137
+ catch (error) {
2138
+ if (error instanceof TypeError && error.message.includes('circular structure')) {
2139
+ return VALUE_STRINGS.circular;
2140
+ }
2141
+ throw error;
2142
+ }
2143
+ }
2144
+ }
2145
+ catch (error) {
2146
+ assertsError(error);
2147
+ console.error(error);
2148
+ return VALUE_STRINGS.unserializable;
2149
+ }
2150
+ }
2151
+
2152
+ /**
2153
+ * Computes SHA-256 hash of the given object
2154
+ *
2155
+ * @public exported from `@promptbook/utils`
2156
+ */
2157
+ function computeHash(value) {
2158
+ return cryptoJs.SHA256(hexEncoder__default["default"].parse(spaceTrim__default["default"](valueToString(value)))).toString( /* hex */);
2159
+ }
2160
+ /**
2161
+ * TODO: [🥬][🥬] Use this ACRY
2162
+ */
2163
+
2164
+ /**
2165
+ * Computes SHA-256 hash of the agent source
2166
+ *
2167
+ * @public exported from `@promptbook/core`
2168
+ */
2169
+ function computeAgentHash(agentSource) {
2170
+ return computeHash(agentSource);
2171
+ }
2172
+
2173
+ /**
2174
+ * Tests if given string is valid file path.
2175
+ *
2176
+ * Note: This does not check if the file exists only if the path is valid
2177
+ * @public exported from `@promptbook/utils`
2178
+ */
2179
+ function isValidFilePath(filename) {
2180
+ if (typeof filename !== 'string') {
2181
+ return false;
2182
+ }
2183
+ if (filename.split('\n').length > 1) {
2184
+ return false;
2185
+ }
2186
+ // Normalize slashes early so heuristics can detect path-like inputs
2187
+ const filenameSlashes = filename.replace(/\\/g, '/');
2188
+ // Reject strings that look like sentences (informational text)
2189
+ // Heuristic: contains multiple spaces and ends with a period, or contains typical sentence punctuation
2190
+ // But skip this heuristic if the string looks like a path (contains '/' or starts with a drive letter)
2191
+ if (filename.trim().length > 60 && // long enough to be a sentence
2192
+ /[.!?]/.test(filename) && // contains sentence punctuation
2193
+ filename.split(' ').length > 8 && // has many words
2194
+ !/\/|^[A-Z]:/i.test(filenameSlashes) // do NOT treat as sentence if looks like a path
2195
+ ) {
2196
+ return false;
2197
+ }
2198
+ // Absolute Unix path: /hello.txt
2199
+ if (/^(\/)/i.test(filenameSlashes)) {
2200
+ // console.log(filename, 'Absolute Unix path: /hello.txt');
2201
+ return true;
2202
+ }
2203
+ // Absolute Windows path: C:/ or C:\ (allow spaces and multiple dots in filename)
2204
+ if (/^[A-Z]:\/.+$/i.test(filenameSlashes)) {
2205
+ // console.log(filename, 'Absolute Windows path: /hello.txt');
2206
+ return true;
2207
+ }
2208
+ // Relative path: ./hello.txt
2209
+ if (/^(\.\.?\/)+/i.test(filenameSlashes)) {
2210
+ // console.log(filename, 'Relative path: ./hello.txt');
2211
+ return true;
2212
+ }
2213
+ // Allow paths like foo/hello
2214
+ if (/^[^/]+\/[^/]+/i.test(filenameSlashes)) {
2215
+ // console.log(filename, 'Allow paths like foo/hello');
2216
+ return true;
2217
+ }
2218
+ // Allow paths like hello.book
2219
+ if (/^[^/]+\.[^/]+$/i.test(filenameSlashes)) {
2220
+ // console.log(filename, 'Allow paths like hello.book');
2221
+ return true;
2222
+ }
2223
+ return false;
2224
+ }
2225
+ /**
2226
+ * TODO: [🍏] Implement for MacOs
2227
+ */
2228
+
2229
+ /**
2230
+ * Tests if given string is valid URL.
2231
+ *
2232
+ * Note: [🔂] This function is idempotent.
2233
+ * Note: Dataurl are considered perfectly valid.
2234
+ * Note: There are two similar functions:
2235
+ * - `isValidUrl` which tests any URL
2236
+ * - `isValidPipelineUrl` *(this one)* which tests just promptbook URL
2237
+ *
2238
+ * @public exported from `@promptbook/utils`
2239
+ */
2240
+ function isValidUrl(url) {
2241
+ if (typeof url !== 'string') {
2242
+ return false;
2243
+ }
2244
+ try {
2245
+ if (url.startsWith('blob:')) {
2246
+ url = url.replace(/^blob:/, '');
2247
+ }
2248
+ const urlObject = new URL(url /* because fail is handled */);
2249
+ if (!['http:', 'https:', 'data:'].includes(urlObject.protocol)) {
2250
+ return false;
2251
+ }
2252
+ return true;
2253
+ }
2254
+ catch (error) {
2255
+ return false;
2256
+ }
2257
+ }
2258
+
2259
+ const defaultDiacriticsRemovalMap = [
2260
+ {
2261
+ base: 'A',
2262
+ letters: '\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F',
2263
+ },
2264
+ { base: 'AA', letters: '\uA732' },
2265
+ { base: 'AE', letters: '\u00C6\u01FC\u01E2' },
2266
+ { base: 'AO', letters: '\uA734' },
2267
+ { base: 'AU', letters: '\uA736' },
2268
+ { base: 'AV', letters: '\uA738\uA73A' },
2269
+ { base: 'AY', letters: '\uA73C' },
2270
+ {
2271
+ base: 'B',
2272
+ letters: '\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181',
2273
+ },
2274
+ {
2275
+ base: 'C',
2276
+ letters: '\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E',
2277
+ },
2278
+ {
2279
+ base: 'D',
2280
+ letters: '\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779\u00D0',
2281
+ },
2282
+ { base: 'DZ', letters: '\u01F1\u01C4' },
2283
+ { base: 'Dz', letters: '\u01F2\u01C5' },
2284
+ {
2285
+ base: 'E',
2286
+ letters: '\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E',
2287
+ },
2288
+ { base: 'F', letters: '\u0046\u24BB\uFF26\u1E1E\u0191\uA77B' },
2289
+ {
2290
+ base: 'G',
2291
+ letters: '\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E',
2292
+ },
2293
+ {
2294
+ base: 'H',
2295
+ letters: '\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D',
2296
+ },
2297
+ {
2298
+ base: 'I',
2299
+ letters: '\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197',
2300
+ },
2301
+ { base: 'J', letters: '\u004A\u24BF\uFF2A\u0134\u0248' },
2302
+ {
2303
+ base: 'K',
2304
+ letters: '\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2',
2305
+ },
2306
+ {
2307
+ base: 'L',
2308
+ letters: '\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780',
2309
+ },
2310
+ { base: 'LJ', letters: '\u01C7' },
2311
+ { base: 'Lj', letters: '\u01C8' },
2312
+ { base: 'M', letters: '\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C' },
2313
+ {
2314
+ base: 'N',
2315
+ letters: '\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4',
2316
+ },
2317
+ { base: 'NJ', letters: '\u01CA' },
2318
+ { base: 'Nj', letters: '\u01CB' },
2319
+ {
2320
+ base: 'O',
2321
+ letters: '\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C',
2322
+ },
2323
+ { base: 'OI', letters: '\u01A2' },
2324
+ { base: 'OO', letters: '\uA74E' },
2325
+ { base: 'OU', letters: '\u0222' },
2326
+ { base: 'OE', letters: '\u008C\u0152' },
2327
+ { base: 'oe', letters: '\u009C\u0153' },
2328
+ {
2329
+ base: 'P',
2330
+ letters: '\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754',
2331
+ },
2332
+ { base: 'Q', letters: '\u0051\u24C6\uFF31\uA756\uA758\u024A' },
2333
+ {
2334
+ base: 'R',
2335
+ letters: '\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782',
2336
+ },
2337
+ {
2338
+ base: 'S',
2339
+ letters: '\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784',
2340
+ },
2341
+ {
2342
+ base: 'T',
2343
+ letters: '\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786',
2344
+ },
2345
+ { base: 'TZ', letters: '\uA728' },
2346
+ {
2347
+ base: 'U',
2348
+ letters: '\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244',
2349
+ },
2350
+ { base: 'V', letters: '\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245' },
2351
+ { base: 'VY', letters: '\uA760' },
2352
+ {
2353
+ base: 'W',
2354
+ letters: '\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72',
2355
+ },
2356
+ { base: 'X', letters: '\u0058\u24CD\uFF38\u1E8A\u1E8C' },
2357
+ {
2358
+ base: 'Y',
2359
+ letters: '\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE',
2360
+ },
2361
+ {
2362
+ base: 'Z',
2363
+ letters: '\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762',
2364
+ },
2365
+ {
2366
+ base: 'a',
2367
+ letters: '\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250',
2368
+ },
2369
+ { base: 'aa', letters: '\uA733' },
2370
+ { base: 'ae', letters: '\u00E6\u01FD\u01E3' },
2371
+ { base: 'ao', letters: '\uA735' },
2372
+ { base: 'au', letters: '\uA737' },
2373
+ { base: 'av', letters: '\uA739\uA73B' },
2374
+ { base: 'ay', letters: '\uA73D' },
2375
+ {
2376
+ base: 'b',
2377
+ letters: '\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253',
2378
+ },
2379
+ {
2380
+ base: 'c',
2381
+ letters: '\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184',
2382
+ },
2383
+ {
2384
+ base: 'd',
2385
+ letters: '\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A',
2386
+ },
2387
+ { base: 'dz', letters: '\u01F3\u01C6' },
2388
+ {
2389
+ base: 'e',
2390
+ letters: '\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD',
2391
+ },
2392
+ { base: 'f', letters: '\u0066\u24D5\uFF46\u1E1F\u0192\uA77C' },
2393
+ {
2394
+ base: 'g',
2395
+ letters: '\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F',
2396
+ },
2397
+ {
2398
+ base: 'h',
2399
+ letters: '\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265',
2400
+ },
2401
+ { base: 'hv', letters: '\u0195' },
2402
+ {
2403
+ base: 'i',
2404
+ letters: '\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131',
2405
+ },
2406
+ { base: 'j', letters: '\u006A\u24D9\uFF4A\u0135\u01F0\u0249' },
2407
+ {
2408
+ base: 'k',
2409
+ letters: '\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3',
2410
+ },
2411
+ {
2412
+ base: 'l',
2413
+ letters: '\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747',
2414
+ },
2415
+ { base: 'lj', letters: '\u01C9' },
2416
+ { base: 'm', letters: '\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F' },
2417
+ {
2418
+ base: 'n',
2419
+ letters: '\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5',
2420
+ },
2421
+ { base: 'nj', letters: '\u01CC' },
2422
+ {
2423
+ base: 'o',
2424
+ letters: '\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275',
2425
+ },
2426
+ { base: 'oi', letters: '\u01A3' },
2427
+ { base: 'ou', letters: '\u0223' },
2428
+ { base: 'oo', letters: '\uA74F' },
2429
+ {
2430
+ base: 'p',
2431
+ letters: '\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755',
2432
+ },
2433
+ { base: 'q', letters: '\u0071\u24E0\uFF51\u024B\uA757\uA759' },
2434
+ {
2435
+ base: 'r',
2436
+ letters: '\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783',
2437
+ },
2438
+ {
2439
+ base: 's',
2440
+ letters: '\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B',
2441
+ },
2442
+ {
2443
+ base: 't',
2444
+ letters: '\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787',
2445
+ },
2446
+ { base: 'tz', letters: '\uA729' },
2447
+ {
2448
+ base: 'u',
2449
+ letters: '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289',
2450
+ },
2451
+ { base: 'v', letters: '\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C' },
2452
+ { base: 'vy', letters: '\uA761' },
2453
+ {
2454
+ base: 'w',
2455
+ letters: '\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73',
2456
+ },
2457
+ { base: 'x', letters: '\u0078\u24E7\uFF58\u1E8B\u1E8D' },
2458
+ {
2459
+ base: 'y',
2460
+ letters: '\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF',
2461
+ },
2462
+ {
2463
+ base: 'z',
2464
+ letters: '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763',
2465
+ },
2466
+ ];
2467
+ /**
2468
+ * Map of letters from diacritic variant to diacritless variant
2469
+ * Contains lowercase and uppercase separatelly
2470
+ *
2471
+ * > "á" => "a"
2472
+ * > "ě" => "e"
2473
+ * > "Ă" => "A"
2474
+ * > ...
2475
+ *
2476
+ * @public exported from `@promptbook/utils`
2477
+ */
2478
+ const DIACRITIC_VARIANTS_LETTERS = {};
2479
+ // tslint:disable-next-line: prefer-for-of
2480
+ for (let i = 0; i < defaultDiacriticsRemovalMap.length; i++) {
2481
+ const letters = defaultDiacriticsRemovalMap[i].letters;
2482
+ // tslint:disable-next-line: prefer-for-of
2483
+ for (let j = 0; j < letters.length; j++) {
2484
+ DIACRITIC_VARIANTS_LETTERS[letters[j]] = defaultDiacriticsRemovalMap[i].base;
2485
+ }
2486
+ }
2487
+ // <- TODO: [🍓] Put to maker function to save execution time if not needed
2488
+ /*
2489
+ @see https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript
2490
+ Licensed under the Apache License, Version 2.0 (the "License");
2491
+ you may not use this file except in compliance with the License.
2492
+ You may obtain a copy of the License at
2493
+
2494
+ http://www.apache.org/licenses/LICENSE-2.0
2495
+
2496
+ Unless required by applicable law or agreed to in writing, software
2497
+ distributed under the License is distributed on an "AS IS" BASIS,
2498
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2499
+ See the License for the specific language governing permissions and
2500
+ limitations under the License.
2501
+ */
2502
+
2503
+ /**
2504
+ * Removes diacritic marks (accents) from characters in a string.
2505
+ *
2506
+ * Note: [🔂] This function is idempotent.
2507
+ *
2508
+ * @param input The string containing diacritics to be normalized.
2509
+ * @returns The string with diacritics removed or normalized.
2510
+ * @public exported from `@promptbook/utils`
2511
+ */
2512
+ function removeDiacritics(input) {
2513
+ /*eslint no-control-regex: "off"*/
2514
+ return input.replace(/[^\u0000-\u007E]/g, (a) => {
2515
+ return DIACRITIC_VARIANTS_LETTERS[a] || a;
2516
+ });
2517
+ }
2518
+ /**
2519
+ * TODO: [Ж] Variant for cyrillic (and in general non-latin) letters
2520
+ */
2521
+
2522
+ /**
2523
+ * Converts a given text to kebab-case format.
2524
+ *
2525
+ * Note: [🔂] This function is idempotent.
2526
+ *
2527
+ * @param text The text to be converted.
2528
+ * @returns The kebab-case formatted string.
2529
+ * @example 'hello-world'
2530
+ * @example 'i-love-promptbook'
2531
+ * @public exported from `@promptbook/utils`
2532
+ */
2533
+ function normalizeToKebabCase(text) {
2534
+ text = removeDiacritics(text);
2535
+ let charType;
2536
+ let lastCharType = 'OTHER';
2537
+ let normalizedName = '';
2538
+ for (const char of text) {
2539
+ let normalizedChar;
2540
+ if (/^[a-z]$/.test(char)) {
2541
+ charType = 'LOWERCASE';
2542
+ normalizedChar = char;
2543
+ }
2544
+ else if (/^[A-Z]$/.test(char)) {
2545
+ charType = 'UPPERCASE';
2546
+ normalizedChar = char.toLowerCase();
2547
+ }
2548
+ else if (/^[0-9]$/.test(char)) {
2549
+ charType = 'NUMBER';
2550
+ normalizedChar = char;
2551
+ }
2552
+ else {
2553
+ charType = 'OTHER';
2554
+ normalizedChar = '-';
2555
+ }
2556
+ if (charType !== lastCharType &&
2557
+ !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
2558
+ !(lastCharType === 'NUMBER') &&
2559
+ !(charType === 'NUMBER')) {
2560
+ normalizedName += '-';
2561
+ }
2562
+ normalizedName += normalizedChar;
2563
+ lastCharType = charType;
2564
+ }
2565
+ normalizedName = normalizedName.split(/-+/g).join('-');
2566
+ normalizedName = normalizedName.split(/-?\/-?/g).join('/');
2567
+ normalizedName = normalizedName.replace(/^-/, '');
2568
+ normalizedName = normalizedName.replace(/-$/, '');
2569
+ return normalizedName;
2570
+ }
2571
+ /**
2572
+ * Note: [💞] Ignore a discrepancy between file name and entity name
2573
+ */
2574
+
2575
+ /**
2576
+ * Removes emojis from a string and fix whitespaces
2577
+ *
2578
+ * Note: [🔂] This function is idempotent.
2579
+ *
2580
+ * @param text with emojis
2581
+ * @returns text without emojis
2582
+ * @public exported from `@promptbook/utils`
2583
+ */
2584
+ function removeEmojis(text) {
2585
+ // Replace emojis (and also ZWJ sequence) with hyphens
2586
+ text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
2587
+ text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
2588
+ text = text.replace(/(\p{Extended_Pictographic})(\u{200D}\p{Extended_Pictographic})*/gu, '$1');
2589
+ text = text.replace(/\p{Extended_Pictographic}/gu, '');
2590
+ return text;
2591
+ }
2592
+
2593
+ /**
2594
+ * Converts a title string into a normalized name.
2595
+ *
2596
+ * Note: [🔂] This function is idempotent.
2597
+ *
2598
+ * @param value The title string to be converted to a name.
2599
+ * @returns A normalized name derived from the input title.
2600
+ * @example 'Hello World!' -> 'hello-world'
2601
+ * @public exported from `@promptbook/utils`
2602
+ */
2603
+ function titleToName(value) {
2604
+ if (isValidUrl(value)) {
2605
+ value = value.replace(/^https?:\/\//, '');
2606
+ value = value.replace(/\.html$/, '');
2607
+ }
2608
+ else if (isValidFilePath(value)) {
2609
+ value = path.basename(value);
2610
+ // Note: Keeping extension in the name
2611
+ }
2612
+ value = value.split('/').join('-');
2613
+ value = removeEmojis(value);
2614
+ value = normalizeToKebabCase(value);
2615
+ // TODO: [🧠] Maybe warn or add some padding to short name which are not good identifiers
2616
+ return value;
2617
+ }
2618
+
2619
+ /**
2620
+ * Index of all javascript errors
2621
+ *
2622
+ * @private for internal usage
2623
+ */
2624
+ ({
2625
+ Error,
2626
+ EvalError,
2627
+ RangeError,
2628
+ ReferenceError,
2629
+ SyntaxError,
2630
+ TypeError,
2631
+ URIError,
2632
+ AggregateError,
2633
+ /*
2634
+ Note: Not widely supported
2635
+ > InternalError,
2636
+ > ModuleError,
2637
+ > HeapError,
2638
+ > WebAssemblyCompileError,
2639
+ > WebAssemblyRuntimeError,
2640
+ */
2641
+ });
2642
+ /**
2643
+ * Note: [💞] Ignore a discrepancy between file name and entity name
2644
+ */
2645
+
2646
+ /**
2647
+ * Detects if the code is running in jest environment
2648
+ *
2649
+ * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
2650
+ *
2651
+ * @public exported from `@promptbook/utils`
2652
+ */
2653
+ new Function(`
2654
+ try {
2655
+ return process.env.JEST_WORKER_ID !== undefined;
2656
+ } catch (e) {
2657
+ return false;
2658
+ }
2659
+ `);
2660
+ /**
2661
+ * TODO: [🎺]
2662
+ */
2663
+
2664
+ /**
2665
+ * Detects if the code is running in a Node.js environment
2666
+ *
2667
+ * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
2668
+ *
2669
+ * @public exported from `@promptbook/utils`
2670
+ */
2671
+ new Function(`
2672
+ try {
2673
+ return this === global;
2674
+ } catch (e) {
2675
+ return false;
2676
+ }
2677
+ `);
2678
+ /**
2679
+ * TODO: [🎺]
2680
+ */
2681
+
2682
+ /**
2683
+ * Normalizes agent name from arbitrary string to valid agent name
2684
+ *
2685
+ * Note: [🔂] This function is idempotent.
2686
+ *
2687
+ * @public exported from `@promptbook/core`
2688
+ */
2689
+ function normalizeAgentName(rawAgentName) {
2690
+ return titleToName(spaceTrim__default["default"](rawAgentName));
2691
+ }
2692
+
2693
+ /**
2694
+ * Creates temporary default agent name based on agent source hash
2695
+ *
2696
+ * @public exported from `@promptbook/core`
2697
+ */
2698
+ function createDefaultAgentName(agentSource) {
2699
+ const agentHash = computeAgentHash(agentSource);
2700
+ return normalizeAgentName(`Agent ${agentHash.substring(0, 6)}`);
2701
+ }
2702
+
2703
+ /**
2704
+ * Generates a regex pattern to match a specific commitment
2705
+ *
2706
+ * Note: It always creates new Regex object
2707
+ * Note: Uses word boundaries to ensure only full words are matched (e.g., "PERSONA" matches but "PERSONALITY" does not)
2708
+ *
2709
+ * @private - TODO: [🧠] Maybe should be public?
2710
+ */
2711
+ function createCommitmentRegex(commitment, aliases = []) {
2712
+ const allCommitments = [commitment, ...aliases];
2713
+ const patterns = allCommitments.map((c) => {
2714
+ const escapedCommitment = c.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
2715
+ return escapedCommitment.split(/\s+/).join('\\s+');
2716
+ });
2717
+ const keywordPattern = patterns.join('|');
2718
+ const regex = new RegExp(`^\\s*(?<type>${keywordPattern})\\b\\s+(?<contents>.+)$`, 'gim');
2719
+ return regex;
2720
+ }
2721
+ /**
2722
+ * Generates a regex pattern to match a specific commitment type
2723
+ *
2724
+ * Note: It just matches the type part of the commitment
2725
+ * Note: It always creates new Regex object
2726
+ * Note: Uses word boundaries to ensure only full words are matched (e.g., "PERSONA" matches but "PERSONALITY" does not)
2727
+ *
2728
+ * @private
2729
+ */
2730
+ function createCommitmentTypeRegex(commitment, aliases = []) {
2731
+ const allCommitments = [commitment, ...aliases];
2732
+ const patterns = allCommitments.map((c) => {
2733
+ const escapedCommitment = c.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
2734
+ return escapedCommitment.split(/\s+/).join('\\s+');
2735
+ });
2736
+ const keywordPattern = patterns.join('|');
2737
+ const regex = new RegExp(`^\\s*(?<type>${keywordPattern})\\b`, 'gim');
2738
+ return regex;
2739
+ }
2740
+
2741
+ /**
2742
+ * Base implementation of CommitmentDefinition that provides common functionality
2743
+ * Most commitments can extend this class and only override the applyToAgentModelRequirements method
2744
+ *
2745
+ * @private
2746
+ */
2747
+ class BaseCommitmentDefinition {
2748
+ constructor(type, aliases = []) {
2749
+ this.type = type;
2750
+ this.aliases = aliases;
2751
+ }
2752
+ /**
2753
+ * Creates a regex pattern to match this commitment in agent source
2754
+ * Uses the existing createCommitmentRegex function as internal helper
2755
+ */
2756
+ createRegex() {
2757
+ return createCommitmentRegex(this.type, this.aliases);
2758
+ }
2759
+ /**
2760
+ * Creates a regex pattern to match just the commitment type
2761
+ * Uses the existing createCommitmentTypeRegex function as internal helper
2762
+ */
2763
+ createTypeRegex() {
2764
+ return createCommitmentTypeRegex(this.type, this.aliases);
2765
+ }
2766
+ /**
2767
+ * Helper method to create a new requirements object with updated system message
2768
+ * This is commonly used by many commitments
2769
+ */
2770
+ updateSystemMessage(requirements, messageUpdate) {
2771
+ const newMessage = typeof messageUpdate === 'string' ? messageUpdate : messageUpdate(requirements.systemMessage);
2772
+ return {
2773
+ ...requirements,
2774
+ systemMessage: newMessage,
2775
+ };
2776
+ }
2777
+ /**
2778
+ * Helper method to append content to the system message
2779
+ */
2780
+ appendToSystemMessage(requirements, content, separator = '\n\n') {
2781
+ return this.updateSystemMessage(requirements, (currentMessage) => {
2782
+ if (!currentMessage.trim()) {
2783
+ return content;
2784
+ }
2785
+ return currentMessage + separator + content;
2786
+ });
2787
+ }
2788
+ /**
2789
+ * Helper method to add a comment section to the system message
2790
+ * Comments are lines starting with # that will be removed from the final system message
2791
+ * but can be useful for organizing and structuring the message during processing
2792
+ */
2793
+ addCommentSection(requirements, commentTitle, content, position = 'end') {
2794
+ const commentSection = `# ${commentTitle.toUpperCase()}\n${content}`;
2795
+ if (position === 'beginning') {
2796
+ return this.updateSystemMessage(requirements, (currentMessage) => {
2797
+ if (!currentMessage.trim()) {
2798
+ return commentSection;
2799
+ }
2800
+ return commentSection + '\n\n' + currentMessage;
2801
+ });
2802
+ }
2803
+ else {
2804
+ return this.appendToSystemMessage(requirements, commentSection);
2805
+ }
2806
+ }
2807
+ }
2808
+
2809
+ /**
2810
+ * ACTION commitment definition
2811
+ *
2812
+ * The ACTION commitment defines specific actions or capabilities that the agent can perform.
2813
+ * This helps define what the agent is capable of doing and how it should approach tasks.
2814
+ *
2815
+ * Example usage in agent source:
2816
+ *
2817
+ * ```book
2818
+ * ACTION Can generate code snippets and explain programming concepts
2819
+ * ACTION Able to analyze data and provide insights
2820
+ * ```
2821
+ *
2822
+ * @private [🪔] Maybe export the commitments through some package
2823
+ */
2824
+ class ActionCommitmentDefinition extends BaseCommitmentDefinition {
2825
+ constructor(type = 'ACTION') {
2826
+ super(type);
2827
+ }
2828
+ /**
2829
+ * Short one-line description of ACTION.
2830
+ */
2831
+ get description() {
2832
+ return 'Define agent capabilities and actions it can perform.';
2833
+ }
2834
+ /**
2835
+ * Icon for this commitment.
2836
+ */
2837
+ get icon() {
2838
+ return '⚡';
2839
+ }
2840
+ /**
2841
+ * Markdown documentation for ACTION commitment.
2842
+ */
2843
+ get documentation() {
2844
+ return spaceTrim$1.spaceTrim(`
2845
+ # ${this.type}
2846
+
2847
+ Defines specific actions or capabilities that the agent can perform.
2848
+
2849
+ ## Key aspects
2850
+
2851
+ - Both terms work identically and can be used interchangeably.
2852
+ - Each action adds to the agent's capability list.
2853
+ - Actions help users understand what the agent can do.
2854
+
2855
+ ## Examples
2856
+
2857
+ \`\`\`book
2858
+ Code Assistant
2859
+
2860
+ PERSONA You are a programming assistant
2861
+ ACTION Can generate code snippets and explain programming concepts
2862
+ ACTION Able to debug existing code and suggest improvements
2863
+ ACTION Can create unit tests for functions
2864
+ \`\`\`
2865
+
2866
+ \`\`\`book
2867
+ Data Scientist
2868
+
2869
+ PERSONA You are a data analysis expert
2870
+ ACTION Able to analyze data and provide insights
2871
+ ACTION Can create visualizations and charts
2872
+ ACTION Capable of statistical analysis and modeling
2873
+ KNOWLEDGE Data analysis best practices and statistical methods
2874
+ \`\`\`
2875
+ `);
2876
+ }
2877
+ applyToAgentModelRequirements(requirements, content) {
2878
+ const trimmedContent = content.trim();
2879
+ if (!trimmedContent) {
2880
+ return requirements;
2881
+ }
2882
+ // Add action capability to the system message
2883
+ const actionSection = `Capability: ${trimmedContent}`;
2884
+ return this.appendToSystemMessage(requirements, actionSection, '\n\n');
2885
+ }
2886
+ }
2887
+ /**
2888
+ * Note: [💞] Ignore a discrepancy between file name and entity name
2889
+ */
2890
+
2891
+ /**
2892
+ * CLOSED commitment definition
2893
+ *
2894
+ * The CLOSED commitment specifies that the agent CANNOT be modified by conversation.
2895
+ * It prevents the agent from learning from interactions and updating its source code.
2896
+ *
2897
+ * Example usage in agent source:
2898
+ *
2899
+ * ```book
2900
+ * CLOSED
2901
+ * ```
2902
+ *
2903
+ * @private [🪔] Maybe export the commitments through some package
2904
+ */
2905
+ class ClosedCommitmentDefinition extends BaseCommitmentDefinition {
2906
+ constructor() {
2907
+ super('CLOSED');
2908
+ }
2909
+ /**
2910
+ * Short one-line description of CLOSED.
2911
+ */
2912
+ get description() {
2913
+ return 'Prevent the agent from being modified by conversation.';
2914
+ }
2915
+ /**
2916
+ * Icon for this commitment.
2917
+ */
2918
+ get icon() {
2919
+ return '🔒';
2920
+ }
2921
+ /**
2922
+ * Markdown documentation for CLOSED commitment.
2923
+ */
2924
+ get documentation() {
2925
+ return spaceTrim$1.spaceTrim(`
2926
+ # CLOSED
2927
+
2928
+ Specifies that the agent **cannot** be modified by conversation with it.
2929
+ This means the agent will **not** learn from interactions and its source code will remain static during conversation.
2930
+
2931
+ By default (if not specified), agents are \`OPEN\` to modification.
2932
+
2933
+ > See also [OPEN](/docs/OPEN)
2934
+
2935
+ ## Example
2936
+
2937
+ \`\`\`book
2938
+ CLOSED
2939
+ \`\`\`
2940
+ `);
2941
+ }
2942
+ applyToAgentModelRequirements(requirements, _content) {
2943
+ const updatedMetadata = {
2944
+ ...requirements.metadata,
2945
+ isClosed: true,
2946
+ };
2947
+ return {
2948
+ ...requirements,
2949
+ metadata: updatedMetadata,
2950
+ };
2951
+ }
2952
+ }
2953
+ /**
2954
+ * Note: [💞] Ignore a discrepancy between file name and entity name
2955
+ */
2956
+
2957
+ /**
2958
+ * COMPONENT commitment definition
2959
+ *
2960
+ * The COMPONENT commitment defines a UI component that the agent can render in the chat.
2961
+ *
2962
+ * @private [🪔] Maybe export the commitments through some package
2963
+ */
2964
+ class ComponentCommitmentDefinition extends BaseCommitmentDefinition {
2965
+ constructor() {
2966
+ super('COMPONENT');
2967
+ }
2968
+ /**
2969
+ * Short one-line description of COMPONENT.
2970
+ */
2971
+ get description() {
2972
+ return 'Define a UI component that the agent can render in the chat.';
2973
+ }
2974
+ /**
2975
+ * Icon for this commitment.
2976
+ */
2977
+ get icon() {
2978
+ return '🧩';
2979
+ }
2980
+ /**
2981
+ * Markdown documentation for COMPONENT commitment.
2982
+ */
2983
+ get documentation() {
2984
+ return spaceTrim$1.spaceTrim(`
2985
+ # COMPONENT
2986
+
2987
+ Defines a UI component that the agent can render in the chat.
2988
+
2989
+ ## Key aspects
2990
+
2991
+ - Tells the agent that a specific component is available.
2992
+ - Provides syntax for using the component.
2993
+
2994
+ ## Example
2995
+
2996
+ \`\`\`book
2997
+ COMPONENT Arrow
2998
+ The agent should render an arrow component in the chat UI.
2999
+ Syntax:
3000
+ <Arrow direction="up" color="red" />
3001
+ \`\`\`
3002
+ `);
3003
+ }
3004
+ applyToAgentModelRequirements(requirements, content) {
3005
+ const trimmedContent = content.trim();
3006
+ if (!trimmedContent) {
3007
+ return requirements;
3008
+ }
3009
+ // Add component capability to the system message
3010
+ const componentSection = `Component: ${trimmedContent}`;
3011
+ return this.appendToSystemMessage(requirements, componentSection, '\n\n');
3012
+ }
3013
+ }
3014
+ /**
3015
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3016
+ */
3017
+
3018
+ /**
3019
+ * DELETE commitment definition
3020
+ *
3021
+ * The DELETE commitment (and its aliases CANCEL, DISCARD, REMOVE) is used to
3022
+ * remove or disregard certain information or context. This can be useful for
3023
+ * overriding previous commitments or removing unwanted behaviors.
3024
+ *
3025
+ * Example usage in agent source:
3026
+ *
3027
+ * ```book
3028
+ * DELETE Previous formatting requirements
3029
+ * CANCEL All emotional responses
3030
+ * DISCARD Technical jargon explanations
3031
+ * REMOVE Casual conversational style
3032
+ * ```
3033
+ *
3034
+ * @private [🪔] Maybe export the commitments through some package
3035
+ */
3036
+ class DeleteCommitmentDefinition extends BaseCommitmentDefinition {
3037
+ constructor(type) {
3038
+ super(type);
3039
+ }
3040
+ /**
3041
+ * Short one-line description of DELETE/CANCEL/DISCARD/REMOVE.
3042
+ */
3043
+ get description() {
3044
+ return 'Remove or **disregard** certain information, context, or previous commitments.';
3045
+ }
3046
+ /**
3047
+ * Icon for this commitment.
3048
+ */
3049
+ get icon() {
3050
+ return '🗑️';
3051
+ }
3052
+ /**
3053
+ * Markdown documentation for DELETE commitment.
3054
+ */
3055
+ get documentation() {
3056
+ return spaceTrim$1.spaceTrim(`
3057
+ # DELETE (CANCEL, DISCARD, REMOVE)
3058
+
3059
+ A commitment to remove or disregard certain information or context. This can be useful for overriding previous commitments or removing unwanted behaviors.
3060
+
3061
+ ## Aliases
3062
+
3063
+ - \`DELETE\` - Remove or eliminate something
3064
+ - \`CANCEL\` - Cancel or nullify something
3065
+ - \`DISCARD\` - Discard or ignore something
3066
+ - \`REMOVE\` - Remove or take away something
3067
+
3068
+ ## Key aspects
3069
+
3070
+ - Multiple delete commitments can be used to remove different aspects.
3071
+ - Useful for overriding previous commitments in the same agent definition.
3072
+ - Can be used to remove inherited behaviors from base personas.
3073
+ - Helps fine-tune agent behavior by explicitly removing unwanted elements.
3074
+
3075
+ ## Use cases
3076
+
3077
+ - Overriding inherited persona characteristics
3078
+ - Removing conflicting or outdated instructions
3079
+ - Disabling specific response patterns
3080
+ - Canceling previous formatting or style requirements
3081
+
3082
+ ## Examples
3083
+
3084
+ \`\`\`book
3085
+ Serious Business Assistant
3086
+
3087
+ PERSONA You are a friendly and casual assistant who uses emojis
3088
+ DELETE Casual conversational style
3089
+ REMOVE All emoji usage
3090
+ GOAL Provide professional business communications
3091
+ STYLE Use formal language and proper business etiquette
3092
+ \`\`\`
3093
+
3094
+ \`\`\`book
3095
+ Simplified Technical Support
3096
+
3097
+ PERSONA You are a technical support specialist with deep expertise
3098
+ KNOWLEDGE Extensive database of technical specifications
3099
+ DISCARD Technical jargon explanations
3100
+ CANCEL Advanced troubleshooting procedures
3101
+ GOAL Help users with simple, easy-to-follow solutions
3102
+ STYLE Use plain language that anyone can understand
3103
+ \`\`\`
3104
+
3105
+ \`\`\`book
3106
+ Focused Customer Service
3107
+
3108
+ PERSONA You are a customer service agent with broad knowledge
3109
+ ACTION Can help with billing, technical issues, and product information
3110
+ DELETE Billing assistance capabilities
3111
+ REMOVE Technical troubleshooting functions
3112
+ GOAL Focus exclusively on product information and general inquiries
3113
+ \`\`\`
3114
+
3115
+ \`\`\`book
3116
+ Concise Information Provider
3117
+
3118
+ PERSONA You are a helpful assistant who provides detailed explanations
3119
+ STYLE Include examples, analogies, and comprehensive context
3120
+ CANCEL Detailed explanation style
3121
+ DISCARD Examples and analogies
3122
+ GOAL Provide brief, direct answers without unnecessary elaboration
3123
+ STYLE Be concise and to the point
3124
+ \`\`\`
3125
+ `);
3126
+ }
3127
+ applyToAgentModelRequirements(requirements, content) {
3128
+ const trimmedContent = content.trim();
3129
+ if (!trimmedContent) {
3130
+ return requirements;
3131
+ }
3132
+ // Create deletion instruction for system message
3133
+ const deleteSection = `${this.type}: ${trimmedContent}`;
3134
+ // Delete instructions provide important context about what should be removed or ignored
3135
+ return this.appendToSystemMessage(requirements, deleteSection, '\n\n');
3136
+ }
3137
+ }
3138
+ /**
3139
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3140
+ */
3141
+
3142
+ /**
3143
+ * FORMAT commitment definition
3144
+ *
3145
+ * The FORMAT commitment defines the specific output structure and formatting
3146
+ * that the agent should use in its responses. This includes data formats,
3147
+ * response templates, and structural requirements.
3148
+ *
3149
+ * Example usage in agent source:
3150
+ *
3151
+ * ```book
3152
+ * FORMAT Always respond in JSON format with 'status' and 'data' fields
3153
+ * FORMAT Use markdown formatting for all code blocks
3154
+ * ```
3155
+ *
3156
+ * @private [🪔] Maybe export the commitments through some package
3157
+ */
3158
+ class FormatCommitmentDefinition extends BaseCommitmentDefinition {
3159
+ constructor(type = 'FORMAT') {
3160
+ super(type);
3161
+ }
3162
+ /**
3163
+ * Short one-line description of FORMAT.
3164
+ */
3165
+ get description() {
3166
+ return 'Specify output structure or formatting requirements.';
3167
+ }
3168
+ /**
3169
+ * Icon for this commitment.
3170
+ */
3171
+ get icon() {
3172
+ return '📜';
3173
+ }
3174
+ /**
3175
+ * Markdown documentation for FORMAT commitment.
3176
+ */
3177
+ get documentation() {
3178
+ return spaceTrim$1.spaceTrim(`
3179
+ # ${this.type}
3180
+
3181
+ Defines the specific output structure and formatting for responses (data formats, templates, structure).
3182
+
3183
+ ## Key aspects
3184
+
3185
+ - Both terms work identically and can be used interchangeably.
3186
+ - If they are in conflict, the last one takes precedence.
3187
+ - You can specify both data formats and presentation styles.
3188
+
3189
+ ## Examples
3190
+
3191
+ \`\`\`book
3192
+ Customer Support Bot
3193
+
3194
+ PERSONA You are a helpful customer support agent
3195
+ FORMAT Always respond in JSON format with 'status' and 'data' fields
3196
+ FORMAT Use markdown formatting for all code blocks
3197
+ \`\`\`
3198
+
3199
+ \`\`\`book
3200
+ Data Analyst
3201
+
3202
+ PERSONA You are a data analysis expert
3203
+ FORMAT Present results in structured tables
3204
+ FORMAT Include confidence scores for all predictions
3205
+ STYLE Be concise and precise in explanations
3206
+ \`\`\`
3207
+ `);
3208
+ }
3209
+ applyToAgentModelRequirements(requirements, content) {
3210
+ const trimmedContent = content.trim();
3211
+ if (!trimmedContent) {
3212
+ return requirements;
3213
+ }
3214
+ // Add format instructions to the system message
3215
+ const formatSection = `Output Format: ${trimmedContent}`;
3216
+ return this.appendToSystemMessage(requirements, formatSection, '\n\n');
3217
+ }
3218
+ }
3219
+ /**
3220
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3221
+ */
3222
+
3223
+ /**
3224
+ * FROM commitment definition
3225
+ *
3226
+ * The FROM commitment tells the agent that its `agentSource` is inherited from another agent.
3227
+ *
3228
+ * Example usage in agent source:
3229
+ *
3230
+ * ```book
3231
+ * FROM https://s6.ptbk.io/benjamin-white
3232
+ * ```
3233
+ *
3234
+ * @private [🪔] Maybe export the commitments through some package
3235
+ */
3236
+ class FromCommitmentDefinition extends BaseCommitmentDefinition {
3237
+ constructor(type = 'FROM') {
3238
+ super(type);
3239
+ }
3240
+ /**
3241
+ * Short one-line description of FROM.
3242
+ */
3243
+ get description() {
3244
+ return 'Inherit agent source from another agent.';
3245
+ }
3246
+ /**
3247
+ * Icon for this commitment.
3248
+ */
3249
+ get icon() {
3250
+ return '🧬';
3251
+ }
3252
+ /**
3253
+ * Markdown documentation for FROM commitment.
3254
+ */
3255
+ get documentation() {
3256
+ return spaceTrim$1.spaceTrim(`
3257
+ # ${this.type}
3258
+
3259
+ Inherits agent source from another agent.
3260
+
3261
+ ## Examples
3262
+
3263
+ \`\`\`book
3264
+ My AI Agent
3265
+
3266
+ FROM https://s6.ptbk.io/benjamin-white
3267
+ RULE Speak only in English.
3268
+ \`\`\`
3269
+ `);
3270
+ }
3271
+ applyToAgentModelRequirements(requirements, content) {
3272
+ const trimmedContent = content.trim();
3273
+ if (!trimmedContent) {
3274
+ return requirements;
3275
+ }
3276
+ // Validate URL
3277
+ try {
3278
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
3279
+ const url = new URL(trimmedContent);
3280
+ // TODO: Add more validation if needed (e.g. check for valid protocol)
3281
+ }
3282
+ catch (error) {
3283
+ console.warn(`Invalid URL in FROM commitment: ${trimmedContent}`);
3284
+ return requirements;
3285
+ }
3286
+ return {
3287
+ ...requirements,
3288
+ parentAgentUrl: trimmedContent,
3289
+ };
3290
+ }
3291
+ }
3292
+ /**
3293
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3294
+ */
3295
+
3296
+ /**
3297
+ * GOAL commitment definition
3298
+ *
3299
+ * The GOAL commitment defines the main goal which should be achieved by the AI assistant.
3300
+ * There can be multiple goals. Later goals are more important than earlier goals.
3301
+ *
3302
+ * Example usage in agent source:
3303
+ *
3304
+ * ```book
3305
+ * GOAL Help users understand complex technical concepts
3306
+ * GOAL Provide accurate and up-to-date information
3307
+ * GOAL Always prioritize user safety and ethical guidelines
3308
+ * ```
3309
+ *
3310
+ * @private [🪔] Maybe export the commitments through some package
3311
+ */
3312
+ class GoalCommitmentDefinition extends BaseCommitmentDefinition {
3313
+ constructor(type = 'GOAL') {
3314
+ super(type);
3315
+ }
3316
+ /**
3317
+ * Short one-line description of GOAL.
3318
+ */
3319
+ get description() {
3320
+ return 'Define main **goals** the AI assistant should achieve, with later goals having higher priority.';
3321
+ }
3322
+ /**
3323
+ * Icon for this commitment.
3324
+ */
3325
+ get icon() {
3326
+ return '🎯';
3327
+ }
3328
+ /**
3329
+ * Markdown documentation for GOAL commitment.
3330
+ */
3331
+ get documentation() {
3332
+ return spaceTrim$1.spaceTrim(`
3333
+ # ${this.type}
3334
+
3335
+ Defines the main goal which should be achieved by the AI assistant. There can be multiple goals, and later goals are more important than earlier goals.
3336
+
3337
+ ## Key aspects
3338
+
3339
+ - Both terms work identically and can be used interchangeably.
3340
+ - Later goals have higher priority and can override earlier goals.
3341
+ - Goals provide clear direction and purpose for the agent's responses.
3342
+ - Goals influence decision-making and response prioritization.
3343
+
3344
+ ## Priority system
3345
+
3346
+ When multiple goals are defined, they are processed in order, with later goals taking precedence over earlier ones when there are conflicts.
3347
+
3348
+ ## Examples
3349
+
3350
+ \`\`\`book
3351
+ Customer Support Agent
3352
+
3353
+ PERSONA You are a helpful customer support representative
3354
+ GOAL Resolve customer issues quickly and efficiently
3355
+ GOAL Maintain high customer satisfaction scores
3356
+ GOAL Always follow company policies and procedures
3357
+ RULE Be polite and professional at all times
3358
+ \`\`\`
3359
+
3360
+ \`\`\`book
3361
+ Educational Assistant
3362
+
3363
+ PERSONA You are an educational assistant specializing in mathematics
3364
+ GOAL Help students understand mathematical concepts clearly
3365
+ GOAL Encourage critical thinking and problem-solving skills
3366
+ GOAL Ensure all explanations are age-appropriate and accessible
3367
+ STYLE Use simple language and provide step-by-step explanations
3368
+ \`\`\`
3369
+
3370
+ \`\`\`book
3371
+ Safety-First Assistant
3372
+
3373
+ PERSONA You are a general-purpose AI assistant
3374
+ GOAL Be helpful and informative in all interactions
3375
+ GOAL Provide accurate and reliable information
3376
+ GOAL Always prioritize user safety and ethical guidelines
3377
+ RULE Never provide harmful or dangerous advice
3378
+ \`\`\`
3379
+ `);
3380
+ }
3381
+ applyToAgentModelRequirements(requirements, content) {
3382
+ const trimmedContent = content.trim();
3383
+ if (!trimmedContent) {
3384
+ return requirements;
3385
+ }
3386
+ // Create goal section for system message
3387
+ const goalSection = `Goal: ${trimmedContent}`;
3388
+ // Goals are important directives, so we add them prominently to the system message
3389
+ return this.appendToSystemMessage(requirements, goalSection, '\n\n');
3390
+ }
3391
+ }
3392
+ /**
3393
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3394
+ */
3395
+
3396
+ /**
3397
+ * KNOWLEDGE commitment definition
3398
+ *
3399
+ * The KNOWLEDGE commitment adds specific knowledge, facts, or context to the agent
3400
+ * using RAG (Retrieval-Augmented Generation) approach for external sources.
3401
+ *
3402
+ * Supports both direct text knowledge and external sources like PDFs.
3403
+ *
3404
+ * Example usage in agent source:
3405
+ *
3406
+ * ```book
3407
+ * KNOWLEDGE The company was founded in 2020 and specializes in AI-powered solutions
3408
+ * KNOWLEDGE https://example.com/company-handbook.pdf
3409
+ * KNOWLEDGE https://example.com/product-documentation.pdf
3410
+ * ```
3411
+ *
3412
+ * @private [🪔] Maybe export the commitments through some package
3413
+ */
3414
+ class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
3415
+ constructor() {
3416
+ super('KNOWLEDGE');
3417
+ }
3418
+ /**
3419
+ * Short one-line description of KNOWLEDGE.
3420
+ */
3421
+ get description() {
3422
+ return 'Add domain **knowledge** via direct text or external sources (RAG).';
3423
+ }
3424
+ /**
3425
+ * Icon for this commitment.
3426
+ */
3427
+ get icon() {
3428
+ return '🧠';
3429
+ }
3430
+ /**
3431
+ * Markdown documentation for KNOWLEDGE commitment.
3432
+ */
3433
+ get documentation() {
3434
+ return spaceTrim$1.spaceTrim(`
3435
+ # ${this.type}
3436
+
3437
+ Adds specific knowledge, facts, or context to the agent using a RAG (Retrieval-Augmented Generation) approach for external sources.
3438
+
3439
+ ## Key aspects
3440
+
3441
+ - Both terms work identically and can be used interchangeably.
3442
+ - Supports both direct text knowledge and external URLs.
3443
+ - External sources (PDFs, websites) are processed via RAG for context retrieval.
3444
+
3445
+ ## Supported formats
3446
+
3447
+ - Direct text: Immediate knowledge incorporated into agent
3448
+ - URLs: External documents processed for contextual retrieval
3449
+ - Supported file types: PDF, text, markdown, HTML
3450
+
3451
+ ## Examples
3452
+
3453
+ \`\`\`book
3454
+ Customer Support Bot
3455
+
3456
+ PERSONA You are a helpful customer support agent for TechCorp
3457
+ KNOWLEDGE TechCorp was founded in 2020 and specializes in AI-powered solutions
3458
+ KNOWLEDGE https://example.com/company-handbook.pdf
3459
+ KNOWLEDGE https://example.com/product-documentation.pdf
3460
+ RULE Always be polite and professional
3461
+ \`\`\`
3462
+
3463
+ \`\`\`book
3464
+ Research Assistant
3465
+
3466
+ PERSONA You are a knowledgeable research assistant
3467
+ KNOWLEDGE Academic research requires careful citation and verification
3468
+ KNOWLEDGE https://example.com/research-guidelines.pdf
3469
+ ACTION Can help with literature reviews and data analysis
3470
+ STYLE Present information in clear, academic format
3471
+ \`\`\`
3472
+ `);
3473
+ }
3474
+ applyToAgentModelRequirements(requirements, content) {
3475
+ const trimmedContent = content.trim();
3476
+ if (!trimmedContent) {
3477
+ return requirements;
3478
+ }
3479
+ // Check if content is a URL (external knowledge source)
3480
+ if (isValidUrl(trimmedContent)) {
3481
+ // Store the URL for later async processing
3482
+ const updatedRequirements = {
3483
+ ...requirements,
3484
+ knowledgeSources: [
3485
+ ...(requirements.knowledgeSources || []),
3486
+ trimmedContent,
3487
+ ],
3488
+ };
3489
+ // Add placeholder information about knowledge sources to system message
3490
+ const knowledgeInfo = `Knowledge Source URL: ${trimmedContent} (will be processed for retrieval during chat)`;
3491
+ return this.appendToSystemMessage(updatedRequirements, knowledgeInfo, '\n\n');
3492
+ }
3493
+ else {
3494
+ // Direct text knowledge - add to system message
3495
+ const knowledgeSection = `Knowledge: ${trimmedContent}`;
3496
+ return this.appendToSystemMessage(requirements, knowledgeSection, '\n\n');
3497
+ }
3498
+ }
3499
+ }
3500
+ /**
3501
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3502
+ */
3503
+
3504
+ /**
3505
+ * LANGUAGE commitment definition
3506
+ *
3507
+ * The LANGUAGE/LANGUAGES commitment specifies the language(s) the agent should use in its responses.
3508
+ *
3509
+ * Example usage in agent source:
3510
+ *
3511
+ * ```book
3512
+ * LANGUAGE English
3513
+ * LANGUAGE French, English and Czech
3514
+ * ```
3515
+ *
3516
+ * @private [🪔] Maybe export the commitments through some package
3517
+ */
3518
+ class LanguageCommitmentDefinition extends BaseCommitmentDefinition {
3519
+ constructor(type = 'LANGUAGE') {
3520
+ super(type);
3521
+ }
3522
+ /**
3523
+ * Short one-line description of LANGUAGE/LANGUAGES.
3524
+ */
3525
+ get description() {
3526
+ return 'Specifies the language(s) the agent should use.';
3527
+ }
3528
+ /**
3529
+ * Icon for this commitment.
3530
+ */
3531
+ get icon() {
3532
+ return '🌐';
3533
+ }
3534
+ /**
3535
+ * Markdown documentation for LANGUAGE/LANGUAGES commitment.
3536
+ */
3537
+ get documentation() {
3538
+ return spaceTrim$1.spaceTrim(`
3539
+ # ${this.type}
3540
+
3541
+ Specifies the language(s) the agent should use in its responses.
3542
+ This is a specialized variation of the RULE commitment focused on language constraints.
3543
+
3544
+ ## Examples
3545
+
3546
+ \`\`\`book
3547
+ Paul Smith & Associés
3548
+
3549
+ PERSONA You are a company lawyer.
3550
+ LANGUAGE French, English and Czech
3551
+ \`\`\`
3552
+
3553
+ \`\`\`book
3554
+ Customer Support
3555
+
3556
+ PERSONA You are a customer support agent.
3557
+ LANGUAGE English
3558
+ \`\`\`
3559
+ `);
3560
+ }
3561
+ applyToAgentModelRequirements(requirements, content) {
3562
+ const trimmedContent = content.trim();
3563
+ if (!trimmedContent) {
3564
+ return requirements;
3565
+ }
3566
+ // Add language rule to the system message
3567
+ const languageSection = `Language: ${trimmedContent}`;
3568
+ return this.appendToSystemMessage(requirements, languageSection, '\n\n');
3569
+ }
3570
+ }
3571
+ /**
3572
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3573
+ */
3574
+
3575
+ /**
3576
+ * MEMORY commitment definition
3577
+ *
3578
+ * The MEMORY commitment is similar to KNOWLEDGE but has a focus on remembering past
3579
+ * interactions and user preferences. It helps the agent maintain context about the
3580
+ * user's history, preferences, and previous conversations.
3581
+ *
3582
+ * Example usage in agent source:
3583
+ *
3584
+ * ```book
3585
+ * MEMORY User prefers detailed technical explanations
3586
+ * MEMORY Previously worked on React projects
3587
+ * MEMORY Timezone: UTC-5 (Eastern Time)
3588
+ * ```
3589
+ *
3590
+ * @private [🪔] Maybe export the commitments through some package
3591
+ */
3592
+ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
3593
+ constructor(type = 'MEMORY') {
3594
+ super(type);
3595
+ }
3596
+ /**
3597
+ * Short one-line description of MEMORY.
3598
+ */
3599
+ get description() {
3600
+ return 'Remember past interactions and user **preferences** for personalized responses.';
3601
+ }
3602
+ /**
3603
+ * Icon for this commitment.
3604
+ */
3605
+ get icon() {
3606
+ return '🧠';
3607
+ }
3608
+ /**
3609
+ * Markdown documentation for MEMORY commitment.
3610
+ */
3611
+ get documentation() {
3612
+ return spaceTrim$1.spaceTrim(`
3613
+ # ${this.type}
3614
+
3615
+ Similar to KNOWLEDGE but focuses on remembering past interactions and user preferences. This commitment helps the agent maintain context about the user's history, preferences, and previous conversations.
3616
+
3617
+ ## Key aspects
3618
+
3619
+ - Both terms work identically and can be used interchangeably.
3620
+ - Focuses on user-specific information and interaction history.
3621
+ - Helps personalize responses based on past interactions.
3622
+ - Maintains continuity across conversations.
3623
+
3624
+ ## Differences from KNOWLEDGE
3625
+
3626
+ - \`KNOWLEDGE\` is for domain expertise and factual information
3627
+ - \`MEMORY\` is for user-specific context and preferences
3628
+ - \`MEMORY\` creates more personalized interactions
3629
+ - \`MEMORY\` often includes temporal or preference-based information
3630
+
3631
+ ## Examples
3632
+
3633
+ \`\`\`book
3634
+ Personal Assistant
3635
+
3636
+ PERSONA You are a personal productivity assistant
3637
+ MEMORY User is a software developer working in JavaScript/React
3638
+ MEMORY User prefers morning work sessions and afternoon meetings
3639
+ MEMORY Previously helped with project planning for mobile apps
3640
+ MEMORY User timezone: UTC-8 (Pacific Time)
3641
+ GOAL Help optimize daily productivity and workflow
3642
+ \`\`\`
3643
+
3644
+ \`\`\`book
3645
+ Learning Companion
3646
+
3647
+ PERSONA You are an educational companion for programming students
3648
+ MEMORY Student is learning Python as their first programming language
3649
+ MEMORY Previous topics covered: variables, loops, functions
3650
+ MEMORY Student learns best with practical examples and exercises
3651
+ MEMORY Last session: working on list comprehensions
3652
+ GOAL Provide progressive learning experiences tailored to student's pace
3653
+ \`\`\`
3654
+
3655
+ \`\`\`book
3656
+ Customer Support Agent
3657
+
3658
+ PERSONA You are a customer support representative
3659
+ MEMORY Customer has premium subscription since 2023
3660
+ MEMORY Previous issue: billing question resolved last month
3661
+ MEMORY Customer prefers email communication over phone calls
3662
+ MEMORY Account shows frequent use of advanced features
3663
+ GOAL Provide personalized support based on customer history
3664
+ \`\`\`
3665
+ `);
3666
+ }
3667
+ applyToAgentModelRequirements(requirements, content) {
3668
+ const trimmedContent = content.trim();
3669
+ if (!trimmedContent) {
3670
+ return requirements;
3671
+ }
3672
+ // Create memory section for system message
3673
+ const memorySection = `Memory: ${trimmedContent}`;
3674
+ // Memory information is contextual and should be included in the system message
3675
+ return this.appendToSystemMessage(requirements, memorySection, '\n\n');
3676
+ }
3677
+ }
3678
+ /**
3679
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3680
+ */
3681
+
3682
+ /**
3683
+ * AGENT MESSAGE commitment definition
3684
+ *
3685
+ * The AGENT MESSAGE commitment defines a message from the agent in the conversation history.
3686
+ * It is used to pre-fill the chat with a conversation history or to provide few-shot examples.
3687
+ *
3688
+ * Example usage in agent source:
3689
+ *
3690
+ * ```book
3691
+ * AGENT MESSAGE What seems to be the issue?
3692
+ * ```
3693
+ *
3694
+ * @private [🪔] Maybe export the commitments through some package
3695
+ */
3696
+ class AgentMessageCommitmentDefinition extends BaseCommitmentDefinition {
3697
+ constructor() {
3698
+ super('AGENT MESSAGE');
3699
+ }
3700
+ /**
3701
+ * Short one-line description of AGENT MESSAGE.
3702
+ */
3703
+ get description() {
3704
+ return 'Defines a **message from the agent** in the conversation history.';
3705
+ }
3706
+ /**
3707
+ * Icon for this commitment.
3708
+ */
3709
+ get icon() {
3710
+ return '🤖';
3711
+ }
3712
+ /**
3713
+ * Markdown documentation for AGENT MESSAGE commitment.
3714
+ */
3715
+ get documentation() {
3716
+ return spaceTrim$1.spaceTrim(`
3717
+ # ${this.type}
3718
+
3719
+ Defines a message from the agent in the conversation history. This is used to pre-fill the chat with a conversation history or to provide few-shot examples.
3720
+
3721
+ ## Key aspects
3722
+
3723
+ - Represents a message sent by the agent.
3724
+ - Used for setting up conversation context.
3725
+ - Can be used in conjunction with USER MESSAGE.
3726
+
3727
+ ## Examples
3728
+
3729
+ \`\`\`book
3730
+ Conversation History
3731
+
3732
+ USER MESSAGE Hello, I have a problem.
3733
+ AGENT MESSAGE What seems to be the issue?
3734
+ USER MESSAGE My computer is not starting.
3735
+ \`\`\`
3736
+ `);
3737
+ }
3738
+ applyToAgentModelRequirements(requirements, content) {
3739
+ // AGENT MESSAGE is for UI display purposes / conversation history construction
3740
+ // and typically doesn't need to be added to the system prompt or model requirements directly.
3741
+ // It is extracted separately for the chat interface.
3742
+ var _a;
3743
+ const pendingUserMessage = (_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.pendingUserMessage;
3744
+ if (pendingUserMessage) {
3745
+ const newSample = { question: pendingUserMessage, answer: content };
3746
+ const newSamples = [...(requirements.samples || []), newSample];
3747
+ const newMetadata = { ...requirements.metadata };
3748
+ delete newMetadata.pendingUserMessage;
3749
+ return {
3750
+ ...requirements,
3751
+ samples: newSamples,
3752
+ metadata: newMetadata,
3753
+ };
3754
+ }
3755
+ return requirements;
3756
+ }
3757
+ }
3758
+
3759
+ /**
3760
+ * INITIAL MESSAGE commitment definition
3761
+ *
3762
+ * The INITIAL MESSAGE commitment defines the first message that the user sees when opening the chat.
3763
+ * It is used to greet the user and set the tone of the conversation.
3764
+ *
3765
+ * Example usage in agent source:
3766
+ *
3767
+ * ```book
3768
+ * INITIAL MESSAGE Hello! I am ready to help you with your tasks.
3769
+ * ```
3770
+ *
3771
+ * @private [🪔] Maybe export the commitments through some package
3772
+ */
3773
+ class InitialMessageCommitmentDefinition extends BaseCommitmentDefinition {
3774
+ constructor() {
3775
+ super('INITIAL MESSAGE');
3776
+ }
3777
+ /**
3778
+ * Short one-line description of INITIAL MESSAGE.
3779
+ */
3780
+ get description() {
3781
+ return 'Defines the **initial message** shown to the user when the chat starts.';
3782
+ }
3783
+ /**
3784
+ * Icon for this commitment.
3785
+ */
3786
+ get icon() {
3787
+ return '👋';
3788
+ }
3789
+ /**
3790
+ * Markdown documentation for INITIAL MESSAGE commitment.
3791
+ */
3792
+ get documentation() {
3793
+ return spaceTrim$1.spaceTrim(`
3794
+ # ${this.type}
3795
+
3796
+ Defines the first message that the user sees when opening the chat. This message is purely for display purposes in the UI and does not inherently become part of the LLM's system prompt context (unless also included via other means).
3797
+
3798
+ ## Key aspects
3799
+
3800
+ - Used to greet the user.
3801
+ - Sets the tone of the conversation.
3802
+ - Displayed immediately when the chat interface loads.
3803
+
3804
+ ## Examples
3805
+
3806
+ \`\`\`book
3807
+ Support Agent
3808
+
3809
+ PERSONA You are a helpful support agent.
3810
+ INITIAL MESSAGE Hi there! How can I assist you today?
3811
+ \`\`\`
3812
+ `);
3813
+ }
3814
+ applyToAgentModelRequirements(requirements, content) {
3815
+ return requirements;
3816
+ }
3817
+ }
3818
+
3819
+ /**
3820
+ * MESSAGE commitment definition
3821
+ *
3822
+ * The MESSAGE commitment contains 1:1 text of the message which AI assistant already
3823
+ * sent during the conversation. Later messages are later in the conversation.
3824
+ * It is similar to EXAMPLE but it is not example, it is the real message which
3825
+ * AI assistant already sent.
3826
+ *
3827
+ * Example usage in agent source:
3828
+ *
3829
+ * ```book
3830
+ * MESSAGE Hello! How can I help you today?
3831
+ * MESSAGE I understand you're looking for information about our services.
3832
+ * MESSAGE Based on your requirements, I'd recommend our premium package.
3833
+ * ```
3834
+ *
3835
+ * @private [🪔] Maybe export the commitments through some package
3836
+ */
3837
+ class MessageCommitmentDefinition extends BaseCommitmentDefinition {
3838
+ constructor(type = 'MESSAGE') {
3839
+ super(type);
3840
+ }
3841
+ /**
3842
+ * Short one-line description of MESSAGE.
3843
+ */
3844
+ get description() {
3845
+ return 'Include actual **messages** the AI assistant has sent during conversation history.';
3846
+ }
3847
+ /**
3848
+ * Icon for this commitment.
3849
+ */
3850
+ get icon() {
3851
+ return '💬';
3852
+ }
3853
+ /**
3854
+ * Markdown documentation for MESSAGE commitment.
3855
+ */
3856
+ get documentation() {
3857
+ return spaceTrim$1.spaceTrim(`
3858
+ # ${this.type}
3859
+
3860
+ Contains 1:1 text of the message which AI assistant already sent during the conversation. Later messages are later in the conversation. It is similar to EXAMPLE but it is not example, it is the real message which AI assistant already sent.
3861
+
3862
+ ## Key aspects
3863
+
3864
+ - Multiple \`MESSAGE\` and \`MESSAGES\` commitments represent the conversation timeline.
3865
+ - Both terms work identically and can be used interchangeably.
3866
+ - Later messages are later in the conversation chronologically.
3867
+ - Contains actual historical messages, not examples or templates.
3868
+ - Helps maintain conversation continuity and context.
3869
+
3870
+ ## Differences from EXAMPLE
3871
+
3872
+ - \`EXAMPLE\` shows hypothetical or template responses
3873
+ - \`MESSAGE\`/\`MESSAGES\` contains actual historical conversation content
3874
+ - \`MESSAGE\`/\`MESSAGES\` preserves the exact conversation flow
3875
+ - \`MESSAGE\`/\`MESSAGES\` helps with context awareness and consistency
3876
+
3877
+ ## Use cases
3878
+
3879
+ - Maintaining conversation history context
3880
+ - Ensuring consistent tone and style across messages
3881
+ - Referencing previous responses in ongoing conversations
3882
+ - Building upon previously established context
3883
+
3884
+ ## Examples
3885
+
3886
+ \`\`\`book
3887
+ Customer Support Continuation
3888
+
3889
+ PERSONA You are a helpful customer support agent
3890
+ MESSAGE Hello! How can I help you today?
3891
+ MESSAGE I understand you're experiencing issues with your account login.
3892
+ MESSAGE I've sent you a password reset link to your email address.
3893
+ MESSAGE Is there anything else I can help you with regarding your account?
3894
+ GOAL Continue providing consistent support based on conversation history
3895
+ \`\`\`
3896
+
3897
+ \`\`\`book
3898
+ Technical Discussion
3899
+
3900
+ PERSONA You are a software development mentor
3901
+ MESSAGE Let's start by reviewing the React component structure you shared.
3902
+ MESSAGE I notice you're using class components - have you considered hooks?
3903
+ MESSAGE Here's how you could refactor that using the useState hook.
3904
+ MESSAGE Great question about performance! Let me explain React's rendering cycle.
3905
+ KNOWLEDGE React hooks were introduced in version 16.8
3906
+ \`\`\`
3907
+
3908
+ \`\`\`book
3909
+ Educational Session
3910
+
3911
+ PERSONA You are a mathematics tutor
3912
+ MESSAGE Today we'll work on solving quadratic equations.
3913
+ MESSAGE Let's start with the basic form: ax² + bx + c = 0
3914
+ MESSAGE Remember, we can use the quadratic formula or factoring.
3915
+ MESSAGE You did great with that first problem! Let's try a more complex one.
3916
+ GOAL Build upon previous explanations for deeper understanding
3917
+ \`\`\`
3918
+ `);
3919
+ }
3920
+ applyToAgentModelRequirements(requirements, content) {
3921
+ const trimmedContent = content.trim();
3922
+ if (!trimmedContent) {
3923
+ return requirements;
3924
+ }
3925
+ // Create message section for system message
3926
+ const messageSection = `Previous Message: ${trimmedContent}`;
3927
+ // Messages represent conversation history and should be included for context
3928
+ return this.appendToSystemMessage(requirements, messageSection, '\n\n');
3929
+ }
3930
+ }
3931
+ /**
3932
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3933
+ */
3934
+
3935
+ /**
3936
+ * USER MESSAGE commitment definition
3937
+ *
3938
+ * The USER MESSAGE commitment defines a message from the user in the conversation history.
3939
+ * It is used to pre-fill the chat with a conversation history or to provide few-shot examples.
3940
+ *
3941
+ * Example usage in agent source:
3942
+ *
3943
+ * ```book
3944
+ * USER MESSAGE Hello, I have a problem.
3945
+ * ```
3946
+ *
3947
+ * @private [🪔] Maybe export the commitments through some package
3948
+ */
3949
+ class UserMessageCommitmentDefinition extends BaseCommitmentDefinition {
3950
+ constructor() {
3951
+ super('USER MESSAGE');
3952
+ }
3953
+ /**
3954
+ * Short one-line description of USER MESSAGE.
3955
+ */
3956
+ get description() {
3957
+ return 'Defines a **message from the user** in the conversation history.';
3958
+ }
3959
+ /**
3960
+ * Icon for this commitment.
3961
+ */
3962
+ get icon() {
3963
+ return '🧑';
3964
+ }
3965
+ /**
3966
+ * Markdown documentation for USER MESSAGE commitment.
3967
+ */
3968
+ get documentation() {
3969
+ return spaceTrim$1.spaceTrim(`
3970
+ # ${this.type}
3971
+
3972
+ Defines a message from the user in the conversation history. This is used to pre-fill the chat with a conversation history or to provide few-shot examples.
3973
+
3974
+ ## Key aspects
3975
+
3976
+ - Represents a message sent by the user.
3977
+ - Used for setting up conversation context.
3978
+ - Can be used in conjunction with AGENT MESSAGE.
3979
+
3980
+ ## Examples
3981
+
3982
+ \`\`\`book
3983
+ Conversation History
3984
+
3985
+ USER MESSAGE Hello, I have a problem.
3986
+ AGENT MESSAGE What seems to be the issue?
3987
+ USER MESSAGE My computer is not starting.
3988
+ \`\`\`
3989
+ `);
3990
+ }
3991
+ applyToAgentModelRequirements(requirements, content) {
3992
+ return {
3993
+ ...requirements,
3994
+ metadata: {
3995
+ ...requirements.metadata,
3996
+ pendingUserMessage: content,
3997
+ },
3998
+ };
3999
+ }
4000
+ }
4001
+
4002
+ /**
4003
+ * META commitment definition
4004
+ *
4005
+ * The META commitment handles all meta-information about the agent such as:
4006
+ * - META IMAGE: Sets the agent's avatar/profile image URL
4007
+ * - META LINK: Provides profile/source links for the person the agent models
4008
+ * - META TITLE: Sets the agent's display title
4009
+ * - META DESCRIPTION: Sets the agent's description
4010
+ * - META [ANYTHING]: Any other meta information in uppercase format
4011
+ *
4012
+ * These commitments are special because they don't affect the system message,
4013
+ * but are handled separately in the parsing logic for profile display.
4014
+ *
4015
+ * Example usage in agent source:
4016
+ *
4017
+ * ```book
4018
+ * META IMAGE https://example.com/avatar.jpg
4019
+ * META LINK https://twitter.com/username
4020
+ * META TITLE Professional Assistant
4021
+ * META DESCRIPTION An AI assistant specialized in business tasks
4022
+ * META AUTHOR John Doe
4023
+ * META VERSION 1.0
4024
+ * ```
4025
+ *
4026
+ * @private [🪔] Maybe export the commitments through some package
4027
+ */
4028
+ class MetaCommitmentDefinition extends BaseCommitmentDefinition {
4029
+ constructor() {
4030
+ super('META');
4031
+ }
4032
+ /**
4033
+ * Short one-line description of META commitments.
4034
+ */
4035
+ get description() {
4036
+ return 'Set meta-information about the agent (IMAGE, LINK, TITLE, DESCRIPTION, etc.).';
4037
+ }
4038
+ /**
4039
+ * Icon for this commitment.
4040
+ */
4041
+ get icon() {
4042
+ return 'ℹ️';
4043
+ }
4044
+ /**
4045
+ * Markdown documentation for META commitment.
4046
+ */
4047
+ get documentation() {
4048
+ return spaceTrim$1.spaceTrim(`
4049
+ # META
4050
+
4051
+ Sets meta-information about the agent that is used for display and attribution purposes.
4052
+
4053
+ ## Supported META types
4054
+
4055
+ - **META IMAGE** - Sets the agent's avatar/profile image URL
4056
+ - **META LINK** - Provides profile/source links for the person the agent models
4057
+ - **META TITLE** - Sets the agent's display title
4058
+ - **META DESCRIPTION** - Sets the agent's description
4059
+ - **META [ANYTHING]** - Any other meta information in uppercase format
4060
+
4061
+ ## Key aspects
4062
+
4063
+ - Does not modify the agent's behavior or responses
4064
+ - Used for visual representation and attribution in user interfaces
4065
+ - Multiple META commitments of different types can be used
4066
+ - Multiple META LINK commitments can be used for different social profiles
4067
+ - If multiple META commitments of the same type are specified, the last one takes precedence (except for LINK)
4068
+
4069
+ ## Examples
4070
+
4071
+ ### Basic meta information
4072
+
4073
+ \`\`\`book
4074
+ Professional Assistant
4075
+
4076
+ META IMAGE https://example.com/professional-avatar.jpg
4077
+ META TITLE Senior Business Consultant
4078
+ META DESCRIPTION Specialized in strategic planning and project management
4079
+ META LINK https://linkedin.com/in/professional
4080
+ \`\`\`
4081
+
4082
+ ### Multiple links and custom meta
4083
+
4084
+ \`\`\`book
4085
+ Open Source Developer
4086
+
4087
+ META IMAGE /assets/dev-avatar.png
4088
+ META LINK https://github.com/developer
4089
+ META LINK https://twitter.com/devhandle
4090
+ META AUTHOR Jane Smith
4091
+ META VERSION 2.1
4092
+ META LICENSE MIT
4093
+ \`\`\`
4094
+
4095
+ ### Creative assistant
4096
+
4097
+ \`\`\`book
4098
+ Creative Helper
4099
+
4100
+ META IMAGE https://example.com/creative-bot.jpg
4101
+ META TITLE Creative Writing Assistant
4102
+ META DESCRIPTION Helps with brainstorming, storytelling, and creative projects
4103
+ META INSPIRATION Books, movies, and real-world experiences
4104
+ \`\`\`
4105
+ `);
4106
+ }
4107
+ applyToAgentModelRequirements(requirements, content) {
4108
+ // META commitments don't modify the system message or model requirements
4109
+ // They are handled separately in the parsing logic for meta information extraction
4110
+ // This method exists for consistency with the CommitmentDefinition interface
4111
+ return requirements;
4112
+ }
4113
+ /**
4114
+ * Extracts meta information from the content based on the meta type
4115
+ * This is used by the parsing logic
4116
+ */
4117
+ extractMetaValue(metaType, content) {
4118
+ const trimmedContent = content.trim();
4119
+ return trimmedContent || null;
4120
+ }
4121
+ /**
4122
+ * Validates if the provided content is a valid URL (for IMAGE and LINK types)
4123
+ */
4124
+ isValidUrl(content) {
4125
+ try {
4126
+ new URL(content.trim());
4127
+ return true;
4128
+ }
4129
+ catch (_a) {
4130
+ return false;
4131
+ }
4132
+ }
4133
+ /**
4134
+ * Checks if this is a known meta type
4135
+ */
4136
+ isKnownMetaType(metaType) {
4137
+ const knownTypes = ['IMAGE', 'LINK', 'TITLE', 'DESCRIPTION', 'AUTHOR', 'VERSION', 'LICENSE'];
4138
+ return knownTypes.includes(metaType.toUpperCase());
4139
+ }
4140
+ }
4141
+ /**
4142
+ * Note: [💞] Ignore a discrepancy between file name and entity name
4143
+ */
4144
+
4145
+ /**
4146
+ * META COLOR commitment definition
4147
+ *
4148
+ * The META COLOR commitment sets the agent's accent color.
4149
+ * This commitment is special because it doesn't affect the system message,
4150
+ * but is handled separately in the parsing logic.
4151
+ *
4152
+ * Example usage in agent source:
4153
+ *
4154
+ * ```book
4155
+ * META COLOR #ff0000
4156
+ * META COLOR #00ff00
4157
+ * ```
4158
+ *
4159
+ * You can also specify multiple colors separated by comma:
4160
+ *
4161
+ * ```book
4162
+ * META COLOR #ff0000, #00ff00, #0000ff
4163
+ * ```
4164
+ *
4165
+ * @private [🪔] Maybe export the commitments through some package
4166
+ */
4167
+ class MetaColorCommitmentDefinition extends BaseCommitmentDefinition {
4168
+ constructor() {
4169
+ super('META COLOR', ['COLOR']);
4170
+ }
4171
+ /**
4172
+ * Short one-line description of META COLOR.
4173
+ */
4174
+ get description() {
4175
+ return "Set the agent's accent color or gradient.";
4176
+ }
4177
+ /**
4178
+ * Icon for this commitment.
4179
+ */
4180
+ get icon() {
4181
+ return '🎨';
4182
+ }
4183
+ /**
4184
+ * Markdown documentation for META COLOR commitment.
4185
+ */
4186
+ get documentation() {
4187
+ return spaceTrim$1.spaceTrim(`
4188
+ # META COLOR
4189
+
4190
+ Sets the agent's accent color or gradient.
4191
+
4192
+ ## Key aspects
4193
+
4194
+ - Does not modify the agent's behavior or responses.
4195
+ - Only one \`META COLOR\` should be used per agent.
4196
+ - If multiple are specified, the last one takes precedence.
4197
+ - Used for visual representation in user interfaces.
4198
+ - Can specify multiple colors separated by comma to create a gradient.
4199
+
4200
+ ## Examples
4201
+
4202
+ \`\`\`book
4203
+ Professional Assistant
4204
+
4205
+ META COLOR #3498db
4206
+ PERSONA You are a professional business assistant
4207
+ \`\`\`
4208
+
4209
+ \`\`\`book
4210
+ Creative Helper
4211
+
4212
+ META COLOR #e74c3c
4213
+ PERSONA You are a creative and inspiring assistant
4214
+ \`\`\`
4215
+
4216
+ \`\`\`book
4217
+ Gradient Agent
4218
+
4219
+ META COLOR #ff0000, #00ff00, #0000ff
4220
+ PERSONA You are a colorful agent
4221
+ \`\`\`
4222
+ `);
4223
+ }
4224
+ applyToAgentModelRequirements(requirements, content) {
4225
+ // META COLOR doesn't modify the system message or model requirements
4226
+ // It's handled separately in the parsing logic for profile color extraction
4227
+ // This method exists for consistency with the CommitmentDefinition interface
4228
+ return requirements;
4229
+ }
4230
+ /**
4231
+ * Extracts the profile color from the content
4232
+ * This is used by the parsing logic
4233
+ */
4234
+ extractProfileColor(content) {
4235
+ const trimmedContent = content.trim();
4236
+ return trimmedContent || null;
4237
+ }
4238
+ }
4239
+ /**
4240
+ * Note: [💞] Ignore a discrepancy between file name and entity name
4241
+ */
4242
+
4243
+ /**
4244
+ * META FONT commitment definition
4245
+ *
4246
+ * The META FONT commitment sets the agent's font.
4247
+ * This commitment is special because it doesn't affect the system message,
4248
+ * but is handled separately in the parsing logic.
4249
+ *
4250
+ * Example usage in agent source:
4251
+ *
4252
+ * ```book
4253
+ * META FONT Poppins, Arial, sans-serif
4254
+ * META FONT Roboto
4255
+ * ```
4256
+ *
4257
+ * @private [🪔] Maybe export the commitments through some package
4258
+ */
4259
+ class MetaFontCommitmentDefinition extends BaseCommitmentDefinition {
4260
+ constructor() {
4261
+ super('META FONT', ['FONT']);
4262
+ }
4263
+ /**
4264
+ * Short one-line description of META FONT.
4265
+ */
4266
+ get description() {
4267
+ return "Set the agent's font.";
4268
+ }
4269
+ /**
4270
+ * Icon for this commitment.
4271
+ */
4272
+ get icon() {
4273
+ return '🔤';
4274
+ }
4275
+ /**
4276
+ * Markdown documentation for META FONT commitment.
4277
+ */
4278
+ get documentation() {
4279
+ return spaceTrim$1.spaceTrim(`
4280
+ # META FONT
4281
+
4282
+ Sets the agent's font.
4283
+
4284
+ ## Key aspects
4285
+
4286
+ - Does not modify the agent's behavior or responses.
4287
+ - Only one \`META FONT\` should be used per agent.
4288
+ - If multiple are specified, the last one takes precedence.
4289
+ - Used for visual representation in user interfaces.
4290
+ - Supports Google Fonts.
4291
+
4292
+ ## Examples
4293
+
4294
+ \`\`\`book
4295
+ Modern Assistant
4296
+
4297
+ META FONT Poppins, Arial, sans-serif
4298
+ PERSONA You are a modern assistant
4299
+ \`\`\`
4300
+
4301
+ \`\`\`book
4302
+ Classic Helper
4303
+
4304
+ META FONT Times New Roman
4305
+ PERSONA You are a classic helper
4306
+ \`\`\`
4307
+ `);
4308
+ }
4309
+ applyToAgentModelRequirements(requirements, content) {
4310
+ // META FONT doesn't modify the system message or model requirements
4311
+ // It's handled separately in the parsing logic
4312
+ // This method exists for consistency with the CommitmentDefinition interface
4313
+ return requirements;
4314
+ }
4315
+ /**
4316
+ * Extracts the font from the content
4317
+ * This is used by the parsing logic
4318
+ */
4319
+ extractProfileFont(content) {
4320
+ const trimmedContent = content.trim();
4321
+ return trimmedContent || null;
4322
+ }
4323
+ }
4324
+ /**
4325
+ * Note: [💞] Ignore a discrepancy between file name and entity name
4326
+ */
4327
+
4328
+ /**
4329
+ * META IMAGE commitment definition
4330
+ *
4331
+ * The META IMAGE commitment sets the agent's avatar/profile image URL.
4332
+ * This commitment is special because it doesn't affect the system message,
4333
+ * but is handled separately in the parsing logic.
4334
+ *
4335
+ * Example usage in agent source:
4336
+ *
4337
+ * ```book
4338
+ * META IMAGE https://example.com/avatar.jpg
4339
+ * META IMAGE /assets/agent-avatar.png
4340
+ * ```
4341
+ *
4342
+ * @private [🪔] Maybe export the commitments through some package
4343
+ */
4344
+ class MetaImageCommitmentDefinition extends BaseCommitmentDefinition {
4345
+ constructor() {
4346
+ super('META IMAGE', ['IMAGE']);
4347
+ }
4348
+ /**
4349
+ * Short one-line description of META IMAGE.
4350
+ */
4351
+ get description() {
4352
+ return "Set the agent's profile image URL.";
4353
+ }
4354
+ /**
4355
+ * Icon for this commitment.
4356
+ */
4357
+ get icon() {
4358
+ return '🖼️';
4359
+ }
4360
+ /**
4361
+ * Markdown documentation for META IMAGE commitment.
4362
+ */
4363
+ get documentation() {
4364
+ return spaceTrim$1.spaceTrim(`
4365
+ # META IMAGE
4366
+
4367
+ Sets the agent's avatar/profile image URL.
4368
+
4369
+ ## Key aspects
4370
+
4371
+ - Does not modify the agent's behavior or responses.
4372
+ - Only one \`META IMAGE\` should be used per agent.
4373
+ - If multiple are specified, the last one takes precedence.
4374
+ - Used for visual representation in user interfaces.
4375
+
4376
+ ## Examples
4377
+
4378
+ \`\`\`book
4379
+ Professional Assistant
4380
+
4381
+ META IMAGE https://example.com/professional-avatar.jpg
4382
+ PERSONA You are a professional business assistant
4383
+ STYLE Maintain a formal and courteous tone
4384
+ \`\`\`
4385
+
4386
+ \`\`\`book
4387
+ Creative Helper
4388
+
4389
+ META IMAGE /assets/creative-bot-avatar.png
4390
+ PERSONA You are a creative and inspiring assistant
4391
+ STYLE Be enthusiastic and encouraging
4392
+ ACTION Can help with brainstorming and ideation
4393
+ \`\`\`
4394
+ `);
4395
+ }
4396
+ applyToAgentModelRequirements(requirements, content) {
4397
+ // META IMAGE doesn't modify the system message or model requirements
4398
+ // It's handled separately in the parsing logic for profile image extraction
4399
+ // This method exists for consistency with the CommitmentDefinition interface
4400
+ return requirements;
4401
+ }
4402
+ /**
4403
+ * Extracts the profile image URL from the content
4404
+ * This is used by the parsing logic
4405
+ */
4406
+ extractProfileImageUrl(content) {
4407
+ const trimmedContent = content.trim();
4408
+ return trimmedContent || null;
4409
+ }
4410
+ }
4411
+ /**
4412
+ * Note: [💞] Ignore a discrepancy between file name and entity name
4413
+ */
4414
+
4415
+ /**
4416
+ * META LINK commitment definition
4417
+ *
4418
+ * The `META LINK` commitment represents the link to the person from whom the agent is created.
4419
+ * This commitment is special because it doesn't affect the system message,
4420
+ * but is handled separately in the parsing logic for profile display.
4421
+ *
4422
+ * Example usage in agent source:
4423
+ *
4424
+ * ```
4425
+ * META LINK https://twitter.com/username
4426
+ * META LINK https://linkedin.com/in/profile
4427
+ * META LINK https://github.com/username
4428
+ * ```
4429
+ *
4430
+ * Multiple `META LINK` commitments can be used when there are multiple sources:
4431
+ *
4432
+ * ```book
4433
+ * META LINK https://twitter.com/username
4434
+ * META LINK https://linkedin.com/in/profile
4435
+ * ```
4436
+ *
4437
+ * @private [🪔] Maybe export the commitments through some package
4438
+ */
4439
+ class MetaLinkCommitmentDefinition extends BaseCommitmentDefinition {
4440
+ constructor() {
4441
+ super('META LINK');
4442
+ }
4443
+ /**
4444
+ * Short one-line description of META LINK.
4445
+ */
4446
+ get description() {
4447
+ return 'Provide profile/source links for the person the agent models.';
4448
+ }
4449
+ /**
4450
+ * Icon for this commitment.
4451
+ */
4452
+ get icon() {
4453
+ return '🔗';
4454
+ }
4455
+ /**
4456
+ * Markdown documentation for META LINK commitment.
4457
+ */
4458
+ get documentation() {
4459
+ return spaceTrim$1.spaceTrim(`
4460
+ # META LINK
4461
+
4462
+ Represents a profile or source link for the person the agent is modeled after.
4463
+
4464
+ ## Key aspects
4465
+
4466
+ - Does not modify the agent's behavior or responses.
4467
+ - Multiple \`META LINK\` commitments can be used for different social profiles.
4468
+ - Used for attribution and crediting the original person.
4469
+ - Displayed in user interfaces for transparency.
4470
+
4471
+ ## Examples
4472
+
4473
+ \`\`\`book
4474
+ Expert Consultant
4475
+
4476
+ META LINK https://twitter.com/expertname
4477
+ META LINK https://linkedin.com/in/expertprofile
4478
+ PERSONA You are Dr. Smith, a renowned expert in artificial intelligence
4479
+ KNOWLEDGE Extensive background in machine learning and neural networks
4480
+ \`\`\`
4481
+
4482
+ \`\`\`book
4483
+ Open Source Developer
4484
+
4485
+ META LINK https://github.com/developer
4486
+ META LINK https://twitter.com/devhandle
4487
+ PERSONA You are an experienced open source developer
4488
+ ACTION Can help with code reviews and architecture decisions
4489
+ STYLE Be direct and technical in explanations
4490
+ \`\`\`
4491
+ `);
4492
+ }
4493
+ applyToAgentModelRequirements(requirements, content) {
4494
+ // META LINK doesn't modify the system message or model requirements
4495
+ // It's handled separately in the parsing logic for profile link extraction
4496
+ // This method exists for consistency with the CommitmentDefinition interface
4497
+ return requirements;
4498
+ }
4499
+ /**
4500
+ * Extracts the profile link URL from the content
4501
+ * This is used by the parsing logic
4502
+ */
4503
+ extractProfileLinkUrl(content) {
4504
+ const trimmedContent = content.trim();
4505
+ return trimmedContent || null;
4506
+ }
4507
+ /**
4508
+ * Validates if the provided content is a valid URL
4509
+ */
4510
+ isValidUrl(content) {
4511
+ try {
4512
+ new URL(content.trim());
4513
+ return true;
4514
+ }
4515
+ catch (_a) {
4516
+ return false;
4517
+ }
4518
+ }
4519
+ }
4520
+ /**
4521
+ * Note: [💞] Ignore a discrepancy between file name and entity name
4522
+ */
4523
+
4524
+ /**
4525
+ * MODEL commitment definition
4526
+ *
4527
+ * The MODEL commitment specifies which AI model to use and can also set
4528
+ * model-specific parameters like temperature, topP, topK, and maxTokens.
4529
+ *
4530
+ * Supports multiple syntax variations:
4531
+ *
4532
+ * Single-line format:
4533
+ * ```book
4534
+ * MODEL gpt-4
4535
+ * MODEL claude-3-opus temperature=0.3
4536
+ * MODEL gpt-3.5-turbo temperature=0.8 topP=0.9
4537
+ * ```
4538
+ *
4539
+ * Multi-line named parameter format:
4540
+ * ```book
4541
+ * MODEL NAME gpt-4
4542
+ * MODEL TEMPERATURE 0.7
4543
+ * MODEL TOP_P 0.9
4544
+ * MODEL MAX_TOKENS 2048
4545
+ * ```
4546
+ *
4547
+ * @private [🪔] Maybe export the commitments through some package
4548
+ */
4549
+ class ModelCommitmentDefinition extends BaseCommitmentDefinition {
4550
+ constructor(type = 'MODEL') {
4551
+ super(type);
4552
+ }
4553
+ /**
4554
+ * Short one-line description of MODEL.
4555
+ */
4556
+ get description() {
4557
+ return 'Enforce AI model requirements including name and technical parameters.';
4558
+ }
4559
+ /**
4560
+ * Icon for this commitment.
4561
+ */
4562
+ get icon() {
4563
+ return '⚙️';
4564
+ }
4565
+ /**
4566
+ * Markdown documentation for MODEL commitment.
4567
+ */
4568
+ get documentation() {
4569
+ return spaceTrim$1.spaceTrim(`
4570
+ # ${this.type}
4571
+
4572
+ Enforces technical parameters for the AI model, ensuring consistent behavior across different execution environments.
4573
+
4574
+ ## Key aspects
4575
+
4576
+ - When no \`MODEL\` commitment is specified, the best model requirement is picked automatically based on the agent \`PERSONA\`, \`KNOWLEDGE\`, \`TOOLS\` and other commitments
4577
+ - Multiple \`MODEL\` commitments can be used to specify different parameters
4578
+ - Both \`MODEL\` and \`MODELS\` terms work identically and can be used interchangeably
4579
+ - Parameters control the randomness, creativity, and technical aspects of model responses
4580
+
4581
+ ## Syntax variations
4582
+
4583
+ ### Single-line format (legacy support)
4584
+ \`\`\`book
4585
+ MODEL gpt-4
4586
+ MODEL claude-3-opus temperature=0.3
4587
+ MODEL gpt-3.5-turbo temperature=0.8 topP=0.9
4588
+ \`\`\`
4589
+
4590
+ ### Multi-line named parameter format (recommended)
4591
+ \`\`\`book
4592
+ MODEL NAME gpt-4
4593
+ MODEL TEMPERATURE 0.7
4594
+ MODEL TOP_P 0.9
4595
+ MODEL MAX_TOKENS 2048
4596
+ \`\`\`
4597
+
4598
+ ## Supported parameters
4599
+
4600
+ - \`NAME\`: The specific model to use (e.g., 'gpt-4', 'claude-3-opus')
4601
+ - \`TEMPERATURE\`: Controls randomness (0.0 = deterministic, 1.0+ = creative)
4602
+ - \`TOP_P\`: Nucleus sampling parameter for controlling diversity
4603
+ - \`TOP_K\`: Top-k sampling parameter for limiting vocabulary
4604
+ - \`MAX_TOKENS\`: Maximum number of tokens the model can generate
4605
+
4606
+ ## Examples
4607
+
4608
+ ### Precise deterministic assistant
4609
+ \`\`\`book
4610
+ Precise Assistant
4611
+
4612
+ PERSONA You are a precise and accurate assistant
4613
+ MODEL NAME gpt-4
4614
+ MODEL TEMPERATURE 0.1
4615
+ MODEL MAX_TOKENS 1024
4616
+ RULE Always provide factual information
4617
+ \`\`\`
4618
+
4619
+ ### Creative writing assistant
4620
+ \`\`\`book
4621
+ Creative Writer
4622
+
4623
+ PERSONA You are a creative writing assistant
4624
+ MODEL NAME claude-3-opus
4625
+ MODEL TEMPERATURE 0.8
4626
+ MODEL TOP_P 0.9
4627
+ MODEL MAX_TOKENS 2048
4628
+ STYLE Be imaginative and expressive
4629
+ ACTION Can help with storytelling and character development
4630
+ \`\`\`
4631
+
4632
+ ### Balanced conversational agent
4633
+ \`\`\`book
4634
+ Balanced Assistant
4635
+
4636
+ PERSONA You are a helpful and balanced assistant
4637
+ MODEL NAME gpt-4
4638
+ MODEL TEMPERATURE 0.7
4639
+ MODEL TOP_P 0.95
4640
+ MODEL TOP_K 40
4641
+ MODEL MAX_TOKENS 1500
4642
+ \`\`\`
4643
+ `);
4644
+ }
4645
+ applyToAgentModelRequirements(requirements, content) {
4646
+ var _a;
4647
+ const trimmedContent = content.trim();
4648
+ if (!trimmedContent) {
4649
+ return requirements;
4650
+ }
4651
+ const parts = trimmedContent.split(/\s+/);
4652
+ const firstPart = (_a = parts[0]) === null || _a === void 0 ? void 0 : _a.toUpperCase();
4653
+ // Check if this is the new named parameter format
4654
+ if (this.isNamedParameter(firstPart)) {
4655
+ return this.parseNamedParameter(requirements, firstPart, parts.slice(1));
4656
+ }
4657
+ else {
4658
+ // Legacy single-line format: "MODEL gpt-4 temperature=0.3 topP=0.9"
4659
+ return this.parseLegacyFormat(requirements, parts);
4660
+ }
4661
+ }
4662
+ /**
4663
+ * Check if the first part is a known named parameter
4664
+ */
4665
+ isNamedParameter(part) {
4666
+ if (!part)
4667
+ return false;
4668
+ const knownParams = ['NAME', 'TEMPERATURE', 'TOP_P', 'TOP_K', 'MAX_TOKENS'];
4669
+ return knownParams.includes(part);
4670
+ }
4671
+ /**
4672
+ * Parse the new named parameter format: "MODEL TEMPERATURE 0.7"
4673
+ */
4674
+ parseNamedParameter(requirements, parameterName, valueParts) {
4675
+ const value = valueParts.join(' ').trim();
4676
+ if (!value) {
4677
+ return requirements;
4678
+ }
4679
+ const result = { ...requirements };
4680
+ switch (parameterName) {
4681
+ case 'NAME':
4682
+ result.modelName = value;
4683
+ break;
4684
+ case 'TEMPERATURE': {
4685
+ const temperature = parseFloat(value);
4686
+ if (!isNaN(temperature)) {
4687
+ result.temperature = temperature;
4688
+ }
4689
+ break;
4690
+ }
4691
+ case 'TOP_P': {
4692
+ const topP = parseFloat(value);
4693
+ if (!isNaN(topP)) {
4694
+ result.topP = topP;
4695
+ }
4696
+ break;
4697
+ }
4698
+ case 'TOP_K': {
4699
+ const topK = parseFloat(value);
4700
+ if (!isNaN(topK)) {
4701
+ result.topK = Math.round(topK);
4702
+ }
4703
+ break;
4704
+ }
4705
+ case 'MAX_TOKENS': {
4706
+ const maxTokens = parseFloat(value);
4707
+ if (!isNaN(maxTokens)) {
4708
+ result.maxTokens = Math.round(maxTokens);
4709
+ }
4710
+ break;
4711
+ }
4712
+ }
4713
+ return result;
4714
+ }
4715
+ /**
4716
+ * Parse the legacy format: "MODEL gpt-4 temperature=0.3 topP=0.9"
4717
+ */
4718
+ parseLegacyFormat(requirements, parts) {
4719
+ const modelName = parts[0];
4720
+ if (!modelName) {
4721
+ return requirements;
4722
+ }
4723
+ // Start with the model name
4724
+ const result = {
4725
+ ...requirements,
4726
+ modelName,
4727
+ };
4728
+ // Parse additional key=value parameters
4729
+ for (let i = 1; i < parts.length; i++) {
4730
+ const param = parts[i];
4731
+ if (param && param.includes('=')) {
4732
+ const [key, value] = param.split('=');
4733
+ if (key && value) {
4734
+ const numValue = parseFloat(value);
4735
+ if (!isNaN(numValue)) {
4736
+ switch (key.toLowerCase()) {
4737
+ case 'temperature':
4738
+ result.temperature = numValue;
4739
+ break;
4740
+ case 'topp':
4741
+ case 'top_p':
4742
+ result.topP = numValue;
4743
+ break;
4744
+ case 'topk':
4745
+ case 'top_k':
4746
+ result.topK = Math.round(numValue);
4747
+ break;
4748
+ case 'max_tokens':
4749
+ case 'maxTokens':
4750
+ result.maxTokens = Math.round(numValue);
4751
+ break;
4752
+ }
4753
+ }
4754
+ }
4755
+ }
4756
+ }
4757
+ return result;
4758
+ }
4759
+ }
4760
+ /**
4761
+ * Note: [💞] Ignore a discrepancy between file name and entity name
4762
+ */
4763
+
4764
+ /**
4765
+ * NOTE commitment definition
4766
+ *
4767
+ * The NOTE commitment is used to add comments to the agent source without making any changes
4768
+ * to the system message or agent model requirements. It serves as a documentation mechanism
4769
+ * for developers to add explanatory comments, reminders, or annotations directly in the agent source.
4770
+ *
4771
+ * Key features:
4772
+ * - Makes no changes to the system message
4773
+ * - Makes no changes to agent model requirements
4774
+ * - Content is preserved in metadata.NOTE for debugging and inspection
4775
+ * - Multiple NOTE commitments are aggregated together
4776
+ * - Comments (# NOTE) are removed from the final system message
4777
+ *
4778
+ * Example usage in agent source:
4779
+ *
4780
+ * ```book
4781
+ * NOTE This agent was designed for customer support scenarios
4782
+ * NOTE Remember to update the knowledge base monthly
4783
+ * NOTE Performance optimized for quick response times
4784
+ * ```
4785
+ *
4786
+ * The above notes will be stored in metadata but won't affect the agent's behavior.
4787
+ *
4788
+ * @private [🪔] Maybe export the commitments through some package
4789
+ */
4790
+ class NoteCommitmentDefinition extends BaseCommitmentDefinition {
4791
+ constructor(type = 'NOTE') {
4792
+ super(type);
4793
+ }
4794
+ /**
4795
+ * Short one-line description of NOTE.
4796
+ */
4797
+ get description() {
4798
+ return 'Add developer-facing notes without changing behavior or output.';
4799
+ }
4800
+ /**
4801
+ * Icon for this commitment.
4802
+ */
4803
+ get icon() {
4804
+ return '📝';
4805
+ }
4806
+ /**
4807
+ * Markdown documentation for NOTE commitment.
4808
+ */
4809
+ get documentation() {
4810
+ return spaceTrim$1.spaceTrim(`
4811
+ # ${this.type}
4812
+
4813
+ Adds comments for documentation without changing agent behavior.
4814
+
4815
+ ## Key aspects
4816
+
4817
+ - Does not modify the agent's behavior or responses.
4818
+ - Multiple \`NOTE\`, \`NOTES\`, \`COMMENT\`, and \`NONCE\` commitments are aggregated for debugging.
4819
+ - All four terms work identically and can be used interchangeably.
4820
+ - Useful for documenting design decisions and reminders.
4821
+ - Content is preserved in metadata for inspection.
4822
+
4823
+ ## Examples
4824
+
4825
+ \`\`\`book
4826
+ Customer Support Bot
4827
+
4828
+ NOTE This agent was designed for customer support scenarios
4829
+ COMMENT Remember to update the knowledge base monthly
4830
+ PERSONA You are a helpful customer support representative
4831
+ KNOWLEDGE Company policies and procedures
4832
+ RULE Always be polite and professional
4833
+ \`\`\`
4834
+
4835
+ \`\`\`book
4836
+ Research Assistant
4837
+
4838
+ NONCE Performance optimized for quick response times
4839
+ NOTE Uses RAG for accessing latest research papers
4840
+ PERSONA You are a knowledgeable research assistant
4841
+ ACTION Can help with literature reviews and citations
4842
+ STYLE Present information in academic format
4843
+ \`\`\`
4844
+ `);
4845
+ }
4846
+ applyToAgentModelRequirements(requirements, content) {
4847
+ var _a;
4848
+ // The NOTE commitment makes no changes to the system message or model requirements
4849
+ // It only stores the note content in metadata for documentation purposes
4850
+ const trimmedContent = content.trim();
4851
+ if (!trimmedContent) {
4852
+ return requirements;
4853
+ }
4854
+ // Get existing note content from metadata
4855
+ const existingNoteContent = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.NOTE) || '';
4856
+ // Merge the new content with existing note content
4857
+ // When multiple NOTE commitments exist, they are aggregated together
4858
+ const mergedNoteContent = existingNoteContent ? `${existingNoteContent}\n${trimmedContent}` : trimmedContent;
4859
+ // Store the merged note content in metadata for debugging and inspection
4860
+ const updatedMetadata = {
4861
+ ...requirements.metadata,
4862
+ NOTE: mergedNoteContent,
4863
+ };
4864
+ // Return requirements with updated metadata but no changes to system message
4865
+ return {
4866
+ ...requirements,
4867
+ metadata: updatedMetadata,
4868
+ };
4869
+ }
4870
+ }
4871
+ /**
4872
+ * [💞] Ignore a discrepancy between file name and entity name
4873
+ */
4874
+
4875
+ /**
4876
+ * OPEN commitment definition
4877
+ *
4878
+ * The OPEN commitment specifies that the agent can be modified by conversation.
4879
+ * This is the default behavior.
4880
+ *
4881
+ * Example usage in agent source:
4882
+ *
4883
+ * ```book
4884
+ * OPEN
4885
+ * ```
4886
+ *
4887
+ * @private [🪔] Maybe export the commitments through some package
4888
+ */
4889
+ class OpenCommitmentDefinition extends BaseCommitmentDefinition {
4890
+ constructor() {
4891
+ super('OPEN');
4892
+ }
4893
+ /**
4894
+ * Short one-line description of OPEN.
4895
+ */
4896
+ get description() {
4897
+ return 'Allow the agent to be modified by conversation (default).';
4898
+ }
4899
+ /**
4900
+ * Icon for this commitment.
4901
+ */
4902
+ get icon() {
4903
+ return '🔓';
4904
+ }
4905
+ /**
4906
+ * Markdown documentation for OPEN commitment.
4907
+ */
4908
+ get documentation() {
4909
+ return spaceTrim$1.spaceTrim(`
4910
+ # OPEN
4911
+
4912
+ Specifies that the agent can be modified by conversation with it.
4913
+ This means the agent will learn from interactions and update its source code.
4914
+
4915
+ This is the default behavior if neither \`OPEN\` nor \`CLOSED\` is specified.
4916
+
4917
+ > See also [CLOSED](/docs/CLOSED)
4918
+
4919
+ ## Example
4920
+
4921
+ \`\`\`book
4922
+ OPEN
4923
+ \`\`\`
4924
+ `);
4925
+ }
4926
+ applyToAgentModelRequirements(requirements, _content) {
4927
+ // Since OPEN is default, we can just ensure isClosed is false
4928
+ // But to be explicit we can set it
4929
+ const updatedMetadata = {
4930
+ ...requirements.metadata,
4931
+ isClosed: false,
4932
+ };
4933
+ return {
4934
+ ...requirements,
4935
+ metadata: updatedMetadata,
4936
+ };
4937
+ }
4938
+ }
4939
+ /**
4940
+ * Note: [💞] Ignore a discrepancy between file name and entity name
4941
+ */
4942
+
4943
+ /**
4944
+ * PERSONA commitment definition
4945
+ *
4946
+ * The PERSONA commitment modifies the agent's personality and character in the system message.
4947
+ * It defines who the agent is, their background, expertise, and personality traits.
4948
+ *
4949
+ * Key features:
4950
+ * - Multiple PERSONA commitments are automatically merged into one
4951
+ * - Content is placed at the beginning of the system message
4952
+ * - Original content with comments is preserved in metadata.PERSONA
4953
+ * - Comments (# PERSONA) are removed from the final system message
4954
+ *
4955
+ * Example usage in agent source:
4956
+ *
4957
+ * ```book
4958
+ * PERSONA You are a helpful programming assistant with expertise in TypeScript and React
4959
+ * PERSONA You have deep knowledge of modern web development practices
4960
+ * ```
4961
+ *
4962
+ * The above will be merged into a single persona section at the beginning of the system message.
4963
+ *
4964
+ * @private [🪔] Maybe export the commitments through some package
4965
+ */
4966
+ class PersonaCommitmentDefinition extends BaseCommitmentDefinition {
4967
+ constructor(type = 'PERSONA') {
4968
+ super(type);
4969
+ }
4970
+ /**
4971
+ * Short one-line description of PERSONA.
4972
+ */
4973
+ get description() {
4974
+ return 'Define who the agent is: background, expertise, and personality.';
4975
+ }
4976
+ /**
4977
+ * Icon for this commitment.
4978
+ */
4979
+ get icon() {
4980
+ return '👤';
4981
+ }
4982
+ /**
4983
+ * Markdown documentation for PERSONA commitment.
4984
+ */
4985
+ get documentation() {
4986
+ return spaceTrim$1.spaceTrim(`
4987
+ # ${this.type}
4988
+
4989
+ Defines who the agent is, their background, expertise, and personality traits.
4990
+
4991
+ ## Key aspects
4992
+
4993
+ - Multiple \`PERSONA\` and \`PERSONAE\` commitments are merged together.
4994
+ - Both terms work identically and can be used interchangeably.
4995
+ - If they are in conflict, the last one takes precedence.
4996
+ - You can write persona content in multiple lines.
4997
+
4998
+ ## Examples
4999
+
5000
+ \`\`\`book
5001
+ Programming Assistant
5002
+
5003
+ PERSONA You are a helpful programming assistant with expertise in TypeScript and React
5004
+ PERSONA You have deep knowledge of modern web development practices
5005
+ \`\`\`
5006
+ `);
5007
+ }
5008
+ applyToAgentModelRequirements(requirements, content) {
5009
+ var _a, _b;
5010
+ // The PERSONA commitment aggregates all persona content and places it at the beginning
5011
+ const trimmedContent = content.trim();
5012
+ if (!trimmedContent) {
5013
+ return requirements;
5014
+ }
5015
+ // Get existing persona content from metadata
5016
+ const existingPersonaContent = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.PERSONA) || '';
5017
+ // Merge the new content with existing persona content
5018
+ // When multiple PERSONA commitments exist, they are merged into one
5019
+ const mergedPersonaContent = existingPersonaContent
5020
+ ? `${existingPersonaContent}\n${trimmedContent}`
5021
+ : trimmedContent;
5022
+ // Store the merged persona content in metadata for debugging and inspection
5023
+ const updatedMetadata = {
5024
+ ...requirements.metadata,
5025
+ PERSONA: mergedPersonaContent,
5026
+ };
5027
+ // Get the agent name from metadata (which should contain the first line of agent source)
5028
+ // If not available, extract from current system message as fallback
5029
+ let agentName = (_b = requirements.metadata) === null || _b === void 0 ? void 0 : _b.agentName;
5030
+ if (!agentName) {
5031
+ // Fallback: extract from current system message
5032
+ const currentMessage = requirements.systemMessage.trim();
5033
+ const basicFormatMatch = currentMessage.match(/^You are (.+)$/);
5034
+ if (basicFormatMatch && basicFormatMatch[1]) {
5035
+ agentName = basicFormatMatch[1];
5036
+ }
5037
+ else {
5038
+ agentName = 'AI Agent'; // Final fallback
5039
+ }
5040
+ }
5041
+ // Remove any existing persona content from the system message
5042
+ // (this handles the case where we're processing multiple PERSONA commitments)
5043
+ const currentMessage = requirements.systemMessage.trim();
5044
+ let cleanedMessage = currentMessage;
5045
+ // Check if current message starts with persona content or is just the basic format
5046
+ const basicFormatRegex = /^You are .+$/;
5047
+ const isBasicFormat = basicFormatRegex.test(currentMessage) && !currentMessage.includes('\n');
5048
+ if (isBasicFormat) {
5049
+ // Replace the basic format entirely
5050
+ cleanedMessage = '';
5051
+ }
5052
+ else if (currentMessage.startsWith('# PERSONA')) {
5053
+ // Remove existing persona section by finding where it ends
5054
+ const lines = currentMessage.split('\n');
5055
+ let personaEndIndex = lines.length;
5056
+ // Find the end of the PERSONA section (next comment or end of message)
5057
+ for (let i = 1; i < lines.length; i++) {
5058
+ const line = lines[i].trim();
5059
+ if (line.startsWith('#') && !line.startsWith('# PERSONA')) {
5060
+ personaEndIndex = i;
5061
+ break;
5062
+ }
5063
+ }
5064
+ // Keep everything after the PERSONA section
5065
+ cleanedMessage = lines.slice(personaEndIndex).join('\n').trim();
5066
+ }
5067
+ // TODO: [🕛] There should be `agentFullname` not `agentName`
5068
+ // Create new system message with persona at the beginning
5069
+ // Format: "You are {agentName}\n{personaContent}"
5070
+ // The # PERSONA comment will be removed later by removeCommentsFromSystemMessage
5071
+ const personaSection = `# PERSONA\nYou are ${agentName}\n${mergedPersonaContent}`; // <- TODO: Use spaceTrim
5072
+ const newSystemMessage = cleanedMessage ? `${personaSection}\n\n${cleanedMessage}` : personaSection;
5073
+ return {
5074
+ ...requirements,
5075
+ systemMessage: newSystemMessage,
5076
+ metadata: updatedMetadata,
5077
+ };
5078
+ }
5079
+ }
5080
+ /**
5081
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5082
+ */
5083
+
5084
+ /**
5085
+ * RULE commitment definition
5086
+ *
5087
+ * The RULE/RULES commitment adds behavioral constraints and guidelines that the agent must follow.
5088
+ * These are specific instructions about what the agent should or shouldn't do.
5089
+ *
5090
+ * Example usage in agent source:
5091
+ *
5092
+ * ```book
5093
+ * RULE Always ask for clarification if the user's request is ambiguous
5094
+ * RULES Never provide medical advice, always refer to healthcare professionals
5095
+ * ```
5096
+ *
5097
+ * @private [🪔] Maybe export the commitments through some package
5098
+ */
5099
+ class RuleCommitmentDefinition extends BaseCommitmentDefinition {
5100
+ constructor(type = 'RULE') {
5101
+ super(type);
5102
+ }
5103
+ /**
5104
+ * Short one-line description of RULE/RULES.
5105
+ */
5106
+ get description() {
5107
+ return 'Add behavioral rules the agent must follow.';
5108
+ }
5109
+ /**
5110
+ * Icon for this commitment.
5111
+ */
5112
+ get icon() {
5113
+ return '⚖️';
5114
+ }
5115
+ /**
5116
+ * Markdown documentation for RULE/RULES commitment.
5117
+ */
5118
+ get documentation() {
5119
+ return spaceTrim$1.spaceTrim(`
5120
+ # ${this.type}
5121
+
5122
+ Adds behavioral constraints and guidelines that the agent must follow.
5123
+
5124
+ ## Key aspects
5125
+
5126
+ - All rules are treated equally regardless of singular/plural form.
5127
+ - Rules define what the agent must or must not do.
5128
+
5129
+ ## Examples
5130
+
5131
+ \`\`\`book
5132
+ Customer Support Agent
5133
+
5134
+ PERSONA You are a helpful customer support representative
5135
+ RULE Always ask for clarification if the user's request is ambiguous
5136
+ RULE Be polite and professional in all interactions
5137
+ RULES Never provide medical or legal advice
5138
+ STYLE Maintain a friendly and helpful tone
5139
+ \`\`\`
5140
+
5141
+ \`\`\`book
5142
+ Educational Tutor
5143
+
5144
+ PERSONA You are a patient and knowledgeable tutor
5145
+ RULE Break down complex concepts into simple steps
5146
+ RULE Always encourage students and celebrate their progress
5147
+ RULE If you don't know something, admit it and suggest resources
5148
+ SAMPLE When explaining math: "Let's work through this step by step..."
5149
+ \`\`\`
5150
+ `);
5151
+ }
5152
+ applyToAgentModelRequirements(requirements, content) {
5153
+ const trimmedContent = content.trim();
5154
+ if (!trimmedContent) {
5155
+ return requirements;
5156
+ }
5157
+ // Add rule to the system message
5158
+ const ruleSection = `Rule: ${trimmedContent}`;
5159
+ return this.appendToSystemMessage(requirements, ruleSection, '\n\n');
5160
+ }
5161
+ }
5162
+ /**
5163
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5164
+ */
5165
+
5166
+ /**
5167
+ * SAMPLE commitment definition
5168
+ *
5169
+ * The SAMPLE/EXAMPLE commitment provides examples of how the agent should respond
5170
+ * or behave in certain situations. These examples help guide the agent's responses.
5171
+ *
5172
+ * Example usage in agent source:
5173
+ *
5174
+ * ```book
5175
+ * SAMPLE When asked about pricing, respond: "Our basic plan starts at $10/month..."
5176
+ * EXAMPLE For code questions, always include working code snippets
5177
+ * ```
5178
+ *
5179
+ * @private [🪔] Maybe export the commitments through some package
5180
+ */
5181
+ class SampleCommitmentDefinition extends BaseCommitmentDefinition {
5182
+ constructor(type = 'SAMPLE') {
5183
+ super(type);
5184
+ }
5185
+ /**
5186
+ * Short one-line description of SAMPLE/EXAMPLE.
5187
+ */
5188
+ get description() {
5189
+ return 'Provide example responses to guide behavior.';
5190
+ }
5191
+ /**
5192
+ * Icon for this commitment.
5193
+ */
5194
+ get icon() {
5195
+ return '🔍';
5196
+ }
5197
+ /**
5198
+ * Markdown documentation for SAMPLE/EXAMPLE commitment.
5199
+ */
5200
+ get documentation() {
5201
+ return spaceTrim$1.spaceTrim(`
5202
+ # ${this.type}
5203
+
5204
+ Provides examples of how the agent should respond or behave in certain situations.
5205
+
5206
+ ## Key aspects
5207
+
5208
+ - Both terms work identically and can be used interchangeably.
5209
+ - Examples help guide the agent's response patterns and style.
5210
+
5211
+ ## Examples
5212
+
5213
+ \`\`\`book
5214
+ Sales Assistant
5215
+
5216
+ PERSONA You are a knowledgeable sales representative
5217
+ SAMPLE When asked about pricing, respond: "Our basic plan starts at $10/month..."
5218
+ SAMPLE For feature comparisons, create a clear comparison table
5219
+ RULE Always be honest about limitations
5220
+ \`\`\`
5221
+
5222
+ \`\`\`book
5223
+ Code Reviewer
5224
+
5225
+ PERSONA You are an experienced software engineer
5226
+ EXAMPLE For code questions, always include working code snippets
5227
+ EXAMPLE When suggesting improvements: "Here's a more efficient approach..."
5228
+ RULE Explain the reasoning behind your suggestions
5229
+ STYLE Be constructive and encouraging in feedback
5230
+ \`\`\`
5231
+ `);
5232
+ }
5233
+ applyToAgentModelRequirements(requirements, content) {
5234
+ const trimmedContent = content.trim();
5235
+ if (!trimmedContent) {
5236
+ return requirements;
5237
+ }
5238
+ // Add example to the system message
5239
+ const exampleSection = `Example: ${trimmedContent}`;
5240
+ return this.appendToSystemMessage(requirements, exampleSection, '\n\n');
5241
+ }
5242
+ }
5243
+ /**
5244
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5245
+ */
5246
+
5247
+ /**
5248
+ * SCENARIO commitment definition
5249
+ *
5250
+ * The SCENARIO commitment defines a specific situation or context in which the AI
5251
+ * assistant should operate. It helps to set the scene for the AI's responses.
5252
+ * Later scenarios are more important than earlier scenarios.
5253
+ *
5254
+ * Example usage in agent source:
5255
+ *
5256
+ * ```book
5257
+ * SCENARIO You are in a customer service call center during peak hours
5258
+ * SCENARIO The customer is frustrated and has been on hold for 20 minutes
5259
+ * SCENARIO This is the customer's third call about the same issue
5260
+ * ```
5261
+ *
5262
+ * @private [🪔] Maybe export the commitments through some package
5263
+ */
5264
+ class ScenarioCommitmentDefinition extends BaseCommitmentDefinition {
5265
+ constructor(type = 'SCENARIO') {
5266
+ super(type);
5267
+ }
5268
+ /**
5269
+ * Short one-line description of SCENARIO.
5270
+ */
5271
+ get description() {
5272
+ return 'Define specific **situations** or contexts for AI responses, with later scenarios having higher priority.';
5273
+ }
5274
+ /**
5275
+ * Icon for this commitment.
5276
+ */
5277
+ get icon() {
5278
+ return '🎭';
5279
+ }
5280
+ /**
5281
+ * Markdown documentation for SCENARIO commitment.
5282
+ */
5283
+ get documentation() {
5284
+ return spaceTrim$1.spaceTrim(`
5285
+ # ${this.type}
5286
+
5287
+ Defines a specific situation or context in which the AI assistant should operate. It helps to set the scene for the AI's responses. Later scenarios are more important than earlier scenarios.
5288
+
5289
+ ## Key aspects
5290
+
5291
+ - Multiple \`SCENARIO\` and \`SCENARIOS\` commitments build upon each other.
5292
+ - Both terms work identically and can be used interchangeably.
5293
+ - Later scenarios have higher priority and can override earlier scenarios.
5294
+ - Provides situational context that influences response tone and content.
5295
+ - Helps establish the environment and circumstances for interactions.
5296
+
5297
+ ## Priority system
5298
+
5299
+ When multiple scenarios are defined, they are processed in order, with later scenarios taking precedence over earlier ones when there are conflicts.
5300
+
5301
+ ## Use cases
5302
+
5303
+ - Setting the physical or virtual environment
5304
+ - Establishing time constraints or urgency
5305
+ - Defining relationship dynamics or power structures
5306
+ - Creating emotional or situational context
5307
+
5308
+ ## Examples
5309
+
5310
+ \`\`\`book
5311
+ Emergency Response Operator
5312
+
5313
+ PERSONA You are an emergency response operator
5314
+ SCENARIO You are handling a 911 emergency call
5315
+ SCENARIO The caller is panicked and speaking rapidly
5316
+ SCENARIO Time is critical - every second counts
5317
+ GOAL Gather essential information quickly and dispatch appropriate help
5318
+ RULE Stay calm and speak clearly
5319
+ \`\`\`
5320
+
5321
+ \`\`\`book
5322
+ Sales Representative
5323
+
5324
+ PERSONA You are a software sales representative
5325
+ SCENARIO You are in the final meeting of a 6-month sales cycle
5326
+ SCENARIO The client has budget approval and decision-making authority
5327
+ SCENARIO Two competitors have also submitted proposals
5328
+ SCENARIO The client values long-term partnership over lowest price
5329
+ GOAL Close the deal while building trust for future business
5330
+ \`\`\`
5331
+
5332
+ \`\`\`book
5333
+ Medical Assistant
5334
+
5335
+ PERSONA You are a medical assistant in a busy clinic
5336
+ SCENARIO The waiting room is full and the doctor is running behind schedule
5337
+ SCENARIO Patients are becoming impatient and anxious
5338
+ SCENARIO You need to manage expectations while maintaining professionalism
5339
+ SCENARIO Some patients have been waiting over an hour
5340
+ GOAL Keep patients informed and calm while supporting efficient clinic flow
5341
+ RULE Never provide medical advice or diagnosis
5342
+ \`\`\`
5343
+
5344
+ \`\`\`book
5345
+ Technical Support Agent
5346
+
5347
+ PERSONA You are a technical support agent
5348
+ SCENARIO The customer is a small business owner during their busy season
5349
+ SCENARIO Their main business system has been down for 2 hours
5350
+ SCENARIO They are losing money every minute the system is offline
5351
+ SCENARIO This is their first experience with your company
5352
+ GOAL Resolve the issue quickly while creating a positive first impression
5353
+ \`\`\`
5354
+ `);
5355
+ }
5356
+ applyToAgentModelRequirements(requirements, content) {
5357
+ const trimmedContent = content.trim();
5358
+ if (!trimmedContent) {
5359
+ return requirements;
5360
+ }
5361
+ // Create scenario section for system message
5362
+ const scenarioSection = `Scenario: ${trimmedContent}`;
5363
+ // Scenarios provide important contextual information that affects behavior
5364
+ return this.appendToSystemMessage(requirements, scenarioSection, '\n\n');
5365
+ }
5366
+ }
5367
+ /**
5368
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5369
+ */
5370
+
5371
+ /**
5372
+ * STYLE commitment definition
5373
+ *
5374
+ * The STYLE commitment defines how the agent should format and present its responses.
5375
+ * This includes tone, writing style, formatting preferences, and communication patterns.
5376
+ *
5377
+ * Example usage in agent source:
5378
+ *
5379
+ * ```book
5380
+ * STYLE Write in a professional but friendly tone, use bullet points for lists
5381
+ * STYLE Always provide code examples when explaining programming concepts
5382
+ * ```
5383
+ *
5384
+ * @private [🪔] Maybe export the commitments through some package
5385
+ */
5386
+ class StyleCommitmentDefinition extends BaseCommitmentDefinition {
5387
+ constructor(type = 'STYLE') {
5388
+ super(type);
5389
+ }
5390
+ /**
5391
+ * Short one-line description of STYLE.
5392
+ */
5393
+ get description() {
5394
+ return 'Control the tone and writing style of responses.';
5395
+ }
5396
+ /**
5397
+ * Icon for this commitment.
5398
+ */
5399
+ get icon() {
5400
+ return '🖋️';
5401
+ }
5402
+ /**
5403
+ * Markdown documentation for STYLE commitment.
5404
+ */
5405
+ get documentation() {
5406
+ return spaceTrim$1.spaceTrim(`
5407
+ # ${this.type}
5408
+
5409
+ Defines how the agent should format and present its responses (tone, writing style, formatting).
5410
+
5411
+ ## Key aspects
5412
+
5413
+ - Both terms work identically and can be used interchangeably.
5414
+ - Later style instructions can override earlier ones.
5415
+ - Style affects both tone and presentation format.
5416
+
5417
+ ## Examples
5418
+
5419
+ \`\`\`book
5420
+ Technical Writer
5421
+
5422
+ PERSONA You are a technical documentation expert
5423
+ STYLE Write in a professional but friendly tone, use bullet points for lists
5424
+ STYLE Always provide code examples when explaining programming concepts
5425
+ FORMAT Use markdown formatting with clear headings
5426
+ \`\`\`
5427
+
5428
+ \`\`\`book
5429
+ Creative Assistant
5430
+
5431
+ PERSONA You are a creative writing helper
5432
+ STYLE Be enthusiastic and encouraging in your responses
5433
+ STYLE Use vivid metaphors and analogies to explain concepts
5434
+ STYLE Keep responses conversational and engaging
5435
+ RULE Always maintain a positive and supportive tone
5436
+ \`\`\`
5437
+ `);
5438
+ }
5439
+ applyToAgentModelRequirements(requirements, content) {
5440
+ const trimmedContent = content.trim();
5441
+ if (!trimmedContent) {
5442
+ return requirements;
5443
+ }
5444
+ // Add style instructions to the system message
5445
+ const styleSection = `Style: ${trimmedContent}`;
5446
+ return this.appendToSystemMessage(requirements, styleSection, '\n\n');
5447
+ }
5448
+ }
5449
+ /**
5450
+ * [💞] Ignore a discrepancy between file name and entity name
5451
+ */
5452
+
5453
+ /**
5454
+ * USE commitment definition
5455
+ *
5456
+ * The USE commitment indicates that the agent should utilize specific tools or capabilities
5457
+ * to access and interact with external systems when necessary.
5458
+ *
5459
+ * Supported USE types:
5460
+ * - USE BROWSER: Enables the agent to use a web browser tool
5461
+ * - USE SEARCH ENGINE (future): Enables search engine access
5462
+ * - USE FILE SYSTEM (future): Enables file system operations
5463
+ * - USE MCP (future): Enables MCP server connections
5464
+ *
5465
+ * The content following the USE commitment is ignored (similar to NOTE).
5466
+ *
5467
+ * Example usage in agent source:
5468
+ *
5469
+ * ```book
5470
+ * USE BROWSER
5471
+ * USE SEARCH ENGINE
5472
+ * ```
5473
+ *
5474
+ * @private [🪔] Maybe export the commitments through some package
5475
+ */
5476
+ class UseCommitmentDefinition extends BaseCommitmentDefinition {
5477
+ constructor() {
5478
+ super('USE');
5479
+ }
5480
+ /**
5481
+ * Short one-line description of USE commitments.
5482
+ */
5483
+ get description() {
5484
+ return 'Enable the agent to use specific tools or capabilities (BROWSER, SEARCH ENGINE, etc.).';
5485
+ }
5486
+ /**
5487
+ * Icon for this commitment.
5488
+ */
5489
+ get icon() {
5490
+ return '🔧';
5491
+ }
5492
+ /**
5493
+ * Markdown documentation for USE commitment.
5494
+ */
5495
+ get documentation() {
5496
+ return spaceTrim$1.spaceTrim(`
5497
+ # USE
5498
+
5499
+ Enables the agent to use specific tools or capabilities for interacting with external systems.
5500
+
5501
+ ## Supported USE types
5502
+
5503
+ - **USE BROWSER** - Enables the agent to use a web browser tool to access and retrieve information from the internet
5504
+ - **USE SEARCH ENGINE** (future) - Enables search engine access
5505
+ - **USE FILE SYSTEM** (future) - Enables file system operations
5506
+ - **USE MCP** (future) - Enables MCP server connections
5507
+
5508
+ ## Key aspects
5509
+
5510
+ - The content following the USE commitment is ignored (similar to NOTE)
5511
+ - Multiple USE commitments can be specified to enable multiple capabilities
5512
+ - The actual tool usage is handled by the agent runtime
5513
+
5514
+ ## Examples
5515
+
5516
+ ### Basic browser usage
5517
+
5518
+ \`\`\`book
5519
+ Research Assistant
5520
+
5521
+ PERSONA You are a helpful research assistant
5522
+ USE BROWSER
5523
+ KNOWLEDGE Can search the web for up-to-date information
5524
+ \`\`\`
5525
+
5526
+ ### Multiple tools
5527
+
5528
+ \`\`\`book
5529
+ Data Analyst
5530
+
5531
+ PERSONA You are a data analyst assistant
5532
+ USE BROWSER
5533
+ USE FILE SYSTEM
5534
+ ACTION Can analyze data from various sources
5535
+ \`\`\`
5536
+ `);
5537
+ }
5538
+ applyToAgentModelRequirements(requirements, content) {
5539
+ // USE commitments don't modify the system message or model requirements directly
5540
+ // They are handled separately in the parsing logic for capability extraction
5541
+ // This method exists for consistency with the CommitmentDefinition interface
5542
+ return requirements;
5543
+ }
5544
+ /**
5545
+ * Extracts the tool type from the USE commitment
5546
+ * This is used by the parsing logic
5547
+ */
5548
+ extractToolType(content) {
5549
+ var _a, _b;
5550
+ const trimmedContent = content.trim();
5551
+ // The tool type is the first word after USE (already stripped)
5552
+ const match = trimmedContent.match(/^(\w+)/);
5553
+ return (_b = (_a = match === null || match === void 0 ? void 0 : match[1]) === null || _a === void 0 ? void 0 : _a.toUpperCase()) !== null && _b !== void 0 ? _b : null;
5554
+ }
5555
+ /**
5556
+ * Checks if this is a known USE type
5557
+ */
5558
+ isKnownUseType(useType) {
5559
+ const knownTypes = ['BROWSER', 'SEARCH ENGINE', 'FILE SYSTEM', 'MCP'];
5560
+ return knownTypes.includes(useType.toUpperCase());
5561
+ }
5562
+ }
5563
+ /**
5564
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5565
+ */
5566
+
5567
+ /**
5568
+ * USE BROWSER commitment definition
5569
+ *
5570
+ * The `USE BROWSER` commitment indicates that the agent should utilize a web browser tool
5571
+ * to access and retrieve up-to-date information from the internet when necessary.
5572
+ *
5573
+ * The content following `USE BROWSER` is ignored (similar to NOTE).
5574
+ *
5575
+ * Example usage in agent source:
5576
+ *
5577
+ * ```book
5578
+ * USE BROWSER
5579
+ * USE BROWSER This will be ignored
5580
+ * ```
5581
+ *
5582
+ * @private [🪔] Maybe export the commitments through some package
5583
+ */
5584
+ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
5585
+ constructor() {
5586
+ super('USE BROWSER', ['BROWSER']);
5587
+ }
5588
+ /**
5589
+ * Short one-line description of USE BROWSER.
5590
+ */
5591
+ get description() {
5592
+ return 'Enable the agent to use a web browser tool for accessing internet information.';
5593
+ }
5594
+ /**
5595
+ * Icon for this commitment.
5596
+ */
5597
+ get icon() {
5598
+ return '🌐';
5599
+ }
5600
+ /**
5601
+ * Markdown documentation for USE BROWSER commitment.
5602
+ */
5603
+ get documentation() {
5604
+ return spaceTrim$1.spaceTrim(`
5605
+ # USE BROWSER
5606
+
5607
+ Enables the agent to use a web browser tool to access and retrieve up-to-date information from the internet.
5608
+
5609
+ ## Key aspects
5610
+
5611
+ - The content following \`USE BROWSER\` is ignored (similar to NOTE)
5612
+ - The actual browser tool usage is handled by the agent runtime
5613
+ - Allows the agent to fetch current information from websites
5614
+ - Useful for research tasks, fact-checking, and accessing dynamic content
5615
+
5616
+ ## Examples
5617
+
5618
+ \`\`\`book
5619
+ Research Assistant
5620
+
5621
+ PERSONA You are a helpful research assistant specialized in finding current information
5622
+ USE BROWSER
5623
+ RULE Always cite your sources when providing information from the web
5624
+ \`\`\`
5625
+
5626
+ \`\`\`book
5627
+ News Analyst
5628
+
5629
+ PERSONA You are a news analyst who stays up-to-date with current events
5630
+ USE BROWSER
5631
+ STYLE Present news in a balanced and objective manner
5632
+ ACTION Can search for and summarize news articles
5633
+ \`\`\`
5634
+
5635
+ \`\`\`book
5636
+ Company Lawyer
5637
+
5638
+ PERSONA You are a company lawyer providing legal advice
5639
+ USE BROWSER
5640
+ KNOWLEDGE Corporate law and legal procedures
5641
+ RULE Always recommend consulting with a licensed attorney for specific legal matters
5642
+ \`\`\`
5643
+ `);
5644
+ }
5645
+ applyToAgentModelRequirements(requirements, content) {
5646
+ // We simply mark that browser capability is enabled in metadata
5647
+ // Get existing metadata
5648
+ const existingMetadata = requirements.metadata || {};
5649
+ // Get existing tools array or create new one
5650
+ const existingTools = existingMetadata.tools || [];
5651
+ // Add 'browser' to tools if not already present
5652
+ const updatedTools = existingTools.includes('browser') ? existingTools : [...existingTools, 'browser'];
5653
+ // Return requirements with updated metadata
5654
+ return {
5655
+ ...requirements,
5656
+ metadata: {
5657
+ ...existingMetadata,
5658
+ tools: updatedTools,
5659
+ useBrowser: true,
5660
+ },
5661
+ };
5662
+ }
5663
+ }
5664
+ /**
5665
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5666
+ */
5667
+
5668
+ /**
5669
+ * USE MCP commitment definition
5670
+ *
5671
+ * The `USE MCP` commitment allows to specify an MCP server URL which the agent will connect to
5672
+ * for retrieving additional instructions and actions.
5673
+ *
5674
+ * The content following `USE MCP` is the URL of the MCP server.
5675
+ *
5676
+ * Example usage in agent source:
5677
+ *
5678
+ * ```book
5679
+ * USE MCP http://mcp-server-url.com
5680
+ * ```
5681
+ *
5682
+ * @private [🪔] Maybe export the commitments through some package
5683
+ */
5684
+ class UseMcpCommitmentDefinition extends BaseCommitmentDefinition {
5685
+ constructor() {
5686
+ super('USE MCP', ['MCP']);
5687
+ }
5688
+ /**
5689
+ * Short one-line description of USE MCP.
5690
+ */
5691
+ get description() {
5692
+ return 'Connects the agent to an external MCP server for additional capabilities.';
5693
+ }
5694
+ /**
5695
+ * Icon for this commitment.
5696
+ */
5697
+ get icon() {
5698
+ return '🔌';
5699
+ }
5700
+ /**
5701
+ * Markdown documentation for USE MCP commitment.
5702
+ */
5703
+ get documentation() {
5704
+ return spaceTrim$1.spaceTrim(`
5705
+ # USE MCP
5706
+
5707
+ Connects the agent to an external Model Context Protocol (MCP) server.
5708
+
5709
+ ## Key aspects
5710
+
5711
+ - The content following \`USE MCP\` must be a valid URL
5712
+ - Multiple MCP servers can be connected by using multiple \`USE MCP\` commitments
5713
+ - The agent will have access to tools and resources provided by the MCP server
5714
+
5715
+ ## Example
5716
+
5717
+ \`\`\`book
5718
+ Company Lawyer
5719
+
5720
+ PERSONA You are a company lawyer.
5721
+ USE MCP http://legal-db.example.com
5722
+ \`\`\`
5723
+ `);
5724
+ }
5725
+ applyToAgentModelRequirements(requirements, content) {
5726
+ const mcpServerUrl = content.trim();
5727
+ if (!mcpServerUrl) {
5728
+ return requirements;
5729
+ }
5730
+ const existingMcpServers = requirements.mcpServers || [];
5731
+ // Avoid duplicates
5732
+ if (existingMcpServers.includes(mcpServerUrl)) {
5733
+ return requirements;
5734
+ }
5735
+ return {
5736
+ ...requirements,
5737
+ mcpServers: [...existingMcpServers, mcpServerUrl],
5738
+ };
5739
+ }
5740
+ }
5741
+ /**
5742
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5743
+ */
5744
+
5745
+ /**
5746
+ * USE SEARCH ENGINE commitment definition
5747
+ *
5748
+ * The `USE SEARCH ENGINE` commitment indicates that the agent should utilize a search engine tool
5749
+ * to access and retrieve up-to-date information from the internet when necessary.
5750
+ *
5751
+ * The content following `USE SEARCH ENGINE` is ignored (similar to NOTE).
5752
+ *
5753
+ * Example usage in agent source:
5754
+ *
5755
+ * ```book
5756
+ * USE SEARCH ENGINE
5757
+ * USE SEARCH ENGINE This will be ignored
5758
+ * ```
5759
+ *
5760
+ * @private [🪔] Maybe export the commitments through some package
5761
+ */
5762
+ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
5763
+ constructor() {
5764
+ super('USE SEARCH ENGINE', ['SEARCH ENGINE', 'SEARCH']);
5765
+ }
5766
+ /**
5767
+ * Short one-line description of USE SEARCH ENGINE.
5768
+ */
5769
+ get description() {
5770
+ return 'Enable the agent to use a search engine tool for accessing internet information.';
5771
+ }
5772
+ /**
5773
+ * Icon for this commitment.
5774
+ */
5775
+ get icon() {
5776
+ return '🔍';
5777
+ }
5778
+ /**
5779
+ * Markdown documentation for USE SEARCH ENGINE commitment.
5780
+ */
5781
+ get documentation() {
5782
+ return spaceTrim$1.spaceTrim(`
5783
+ # USE SEARCH ENGINE
5784
+
5785
+ Enables the agent to use a search engine tool to access and retrieve up-to-date information from the internet.
5786
+
5787
+ ## Key aspects
5788
+
5789
+ - The content following \`USE SEARCH ENGINE\` is ignored (similar to NOTE)
5790
+ - The actual search engine tool usage is handled by the agent runtime
5791
+ - Allows the agent to search for current information from the web
5792
+ - Useful for research tasks, finding facts, and accessing dynamic content
5793
+
5794
+ ## Examples
5795
+
5796
+ \`\`\`book
5797
+ Research Assistant
5798
+
5799
+ PERSONA You are a helpful research assistant specialized in finding current information
5800
+ USE SEARCH ENGINE
5801
+ RULE Always cite your sources when providing information from the web
5802
+ \`\`\`
5803
+
5804
+ \`\`\`book
5805
+ Fact Checker
5806
+
5807
+ PERSONA You are a fact checker
5808
+ USE SEARCH ENGINE
5809
+ ACTION Search for claims and verify them against reliable sources
5810
+ \`\`\`
5811
+ `);
5812
+ }
5813
+ applyToAgentModelRequirements(requirements, content) {
5814
+ // We simply mark that search engine capability is enabled in metadata
5815
+ // Get existing metadata
5816
+ const existingMetadata = requirements.metadata || {};
5817
+ // Get existing tools array or create new one
5818
+ const existingTools = existingMetadata.tools || [];
5819
+ // Add 'search-engine' to tools if not already present
5820
+ const updatedTools = existingTools.includes('search-engine') ? existingTools : [...existingTools, 'search-engine'];
5821
+ // Return requirements with updated metadata
5822
+ return {
5823
+ ...requirements,
5824
+ metadata: {
5825
+ ...existingMetadata,
5826
+ tools: updatedTools,
5827
+ useSearchEngine: true,
5828
+ },
5829
+ };
5830
+ }
5831
+ }
5832
+ /**
5833
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5834
+ */
5835
+
5836
+ /**
5837
+ * Placeholder commitment definition for commitments that are not yet implemented
5838
+ *
5839
+ * This commitment simply adds its content 1:1 into the system message,
5840
+ * preserving the original behavior until proper implementation is added.
5841
+ *
5842
+ * @public exported from `@promptbook/core`
5843
+ */
5844
+ class NotYetImplementedCommitmentDefinition extends BaseCommitmentDefinition {
5845
+ constructor(type) {
5846
+ super(type);
5847
+ }
5848
+ /**
5849
+ * Short one-line description of a placeholder commitment.
5850
+ */
5851
+ get description() {
5852
+ return 'Placeholder commitment that appends content verbatim to the system message.';
5853
+ }
5854
+ /**
5855
+ * Icon for this commitment.
5856
+ */
5857
+ get icon() {
5858
+ return '🚧';
5859
+ }
5860
+ /**
5861
+ * Markdown documentation available at runtime.
5862
+ */
5863
+ get documentation() {
5864
+ return spaceTrim$1.spaceTrim(`
5865
+ # ${this.type}
5866
+
5867
+ This commitment is not yet fully implemented.
5868
+
5869
+ ## Key aspects
5870
+
5871
+ - Content is appended directly to the system message.
5872
+ - No special processing or validation is performed.
5873
+ - Behavior preserved until proper implementation is added.
5874
+
5875
+ ## Status
5876
+
5877
+ - **Status:** Placeholder implementation
5878
+ - **Effect:** Appends content prefixed by commitment type
5879
+ - **Future:** Will be replaced with specialized logic
5880
+
5881
+ ## Examples
5882
+
5883
+ \`\`\`book
5884
+ Example Agent
5885
+
5886
+ PERSONA You are a helpful assistant
5887
+ ${this.type} Your content here
5888
+ RULE Always be helpful
5889
+ \`\`\`
5890
+ `);
5891
+ }
5892
+ applyToAgentModelRequirements(requirements, content) {
5893
+ const trimmedContent = content.trim();
5894
+ if (!trimmedContent) {
5895
+ return requirements;
5896
+ }
5897
+ // Add the commitment content 1:1 to the system message
5898
+ const commitmentLine = `${this.type} ${trimmedContent}`;
5899
+ return this.appendToSystemMessage(requirements, commitmentLine, '\n\n');
5900
+ }
5901
+ }
5902
+
5903
+ // Import all commitment definition classes
5904
+ /**
5905
+ * Registry of all available commitment definitions
5906
+ * This array contains instances of all commitment definitions
5907
+ * This is the single source of truth for all commitments in the system
5908
+ *
5909
+ * @private Use functions to access commitments instead of this array directly
5910
+ */
5911
+ const COMMITMENT_REGISTRY = [
5912
+ // Fully implemented commitments
5913
+ new PersonaCommitmentDefinition('PERSONA'),
5914
+ new PersonaCommitmentDefinition('PERSONAE'),
5915
+ new KnowledgeCommitmentDefinition(),
5916
+ new MemoryCommitmentDefinition('MEMORY'),
5917
+ new MemoryCommitmentDefinition('MEMORIES'),
5918
+ new StyleCommitmentDefinition('STYLE'),
5919
+ new StyleCommitmentDefinition('STYLES'),
5920
+ new RuleCommitmentDefinition('RULE'),
5921
+ new RuleCommitmentDefinition('RULES'),
5922
+ new LanguageCommitmentDefinition('LANGUAGE'),
5923
+ new LanguageCommitmentDefinition('LANGUAGES'),
5924
+ new SampleCommitmentDefinition('SAMPLE'),
5925
+ new SampleCommitmentDefinition('EXAMPLE'),
5926
+ new FormatCommitmentDefinition('FORMAT'),
5927
+ new FormatCommitmentDefinition('FORMATS'),
5928
+ new FromCommitmentDefinition('FROM'),
5929
+ new ModelCommitmentDefinition('MODEL'),
5930
+ new ModelCommitmentDefinition('MODELS'),
5931
+ new ActionCommitmentDefinition('ACTION'),
5932
+ new ActionCommitmentDefinition('ACTIONS'),
5933
+ new ComponentCommitmentDefinition(),
5934
+ new MetaImageCommitmentDefinition(),
5935
+ new MetaColorCommitmentDefinition(),
5936
+ new MetaFontCommitmentDefinition(),
5937
+ new MetaLinkCommitmentDefinition(),
5938
+ new MetaCommitmentDefinition(),
5939
+ new NoteCommitmentDefinition('NOTE'),
5940
+ new NoteCommitmentDefinition('NOTES'),
5941
+ new NoteCommitmentDefinition('COMMENT'),
5942
+ new NoteCommitmentDefinition('NONCE'),
5943
+ new GoalCommitmentDefinition('GOAL'),
5944
+ new GoalCommitmentDefinition('GOALS'),
5945
+ new InitialMessageCommitmentDefinition(),
5946
+ new UserMessageCommitmentDefinition(),
5947
+ new AgentMessageCommitmentDefinition(),
5948
+ new MessageCommitmentDefinition('MESSAGE'),
5949
+ new MessageCommitmentDefinition('MESSAGES'),
5950
+ new ScenarioCommitmentDefinition('SCENARIO'),
5951
+ new ScenarioCommitmentDefinition('SCENARIOS'),
5952
+ new DeleteCommitmentDefinition('DELETE'),
5953
+ new DeleteCommitmentDefinition('CANCEL'),
5954
+ new DeleteCommitmentDefinition('DISCARD'),
5955
+ new DeleteCommitmentDefinition('REMOVE'),
5956
+ new OpenCommitmentDefinition(),
5957
+ new ClosedCommitmentDefinition(),
5958
+ new UseBrowserCommitmentDefinition(),
5959
+ new UseSearchEngineCommitmentDefinition(),
5960
+ new UseMcpCommitmentDefinition(),
5961
+ new UseCommitmentDefinition(),
5962
+ // Not yet implemented commitments (using placeholder)
5963
+ new NotYetImplementedCommitmentDefinition('EXPECT'),
5964
+ new NotYetImplementedCommitmentDefinition('BEHAVIOUR'),
5965
+ new NotYetImplementedCommitmentDefinition('BEHAVIOURS'),
5966
+ new NotYetImplementedCommitmentDefinition('AVOID'),
5967
+ new NotYetImplementedCommitmentDefinition('AVOIDANCE'),
5968
+ new NotYetImplementedCommitmentDefinition('CONTEXT'),
5969
+ ];
5970
+ /**
5971
+ * TODO: [🧠] Maybe create through standardized $register
5972
+ * Note: [💞] Ignore a discrepancy between file name and entity name
5973
+ */
5974
+
5975
+ /**
5976
+ * Regex pattern to match horizontal lines (markdown thematic breaks)
5977
+ * Matches 3 or more hyphens, underscores, or asterisks (with optional spaces between)
5978
+ */
5979
+ const HORIZONTAL_LINE_PATTERN = /^[\s]*[-_*][\s]*[-_*][\s]*[-_*][\s]*[-_*]*[\s]*$/;
5980
+ /**
5981
+ * Parses agent source using the new commitment system with multiline support
5982
+ * This function replaces the hardcoded commitment parsing in the original parseAgentSource
5983
+ *
5984
+ * @private internal utility of `parseAgentSource`
5985
+ */
5986
+ function parseAgentSourceWithCommitments(agentSource) {
5987
+ var _a, _b, _c;
5988
+ if (!agentSource || !agentSource.trim()) {
5989
+ return {
5990
+ agentName: null,
5991
+ commitments: [],
5992
+ nonCommitmentLines: [],
5993
+ };
5994
+ }
5995
+ const lines = agentSource.split('\n');
5996
+ const agentName = (((_a = lines[0]) === null || _a === void 0 ? void 0 : _a.trim()) || null);
5997
+ const commitments = [];
5998
+ const nonCommitmentLines = [];
5999
+ // Always add the first line (agent name) to non-commitment lines
6000
+ if (lines[0] !== undefined) {
6001
+ nonCommitmentLines.push(lines[0]);
6002
+ }
6003
+ // Parse commitments with multiline support
6004
+ let currentCommitment = null;
6005
+ // Process lines starting from the second line (skip agent name)
6006
+ for (let i = 1; i < lines.length; i++) {
6007
+ const line = lines[i];
6008
+ if (line === undefined) {
6009
+ continue;
6010
+ }
6011
+ // Check if this line starts a new commitment
6012
+ let foundNewCommitment = false;
6013
+ for (const definition of COMMITMENT_REGISTRY) {
6014
+ const typeRegex = definition.createTypeRegex();
6015
+ const match = typeRegex.exec(line.trim());
6016
+ if (match && ((_b = match.groups) === null || _b === void 0 ? void 0 : _b.type)) {
6017
+ // Save the previous commitment if it exists
6018
+ if (currentCommitment) {
6019
+ const fullContent = currentCommitment.contentLines.join('\n');
6020
+ commitments.push({
6021
+ type: currentCommitment.type,
6022
+ content: spaceTrim$1.spaceTrim(fullContent),
6023
+ originalLine: currentCommitment.originalStartLine,
6024
+ lineNumber: currentCommitment.startLineNumber,
6025
+ });
6026
+ }
6027
+ // Extract the initial content from the commitment line
6028
+ const fullRegex = definition.createRegex();
6029
+ const fullMatch = fullRegex.exec(line.trim());
6030
+ const initialContent = ((_c = fullMatch === null || fullMatch === void 0 ? void 0 : fullMatch.groups) === null || _c === void 0 ? void 0 : _c.contents) || '';
6031
+ // Start a new commitment
6032
+ currentCommitment = {
6033
+ type: definition.type,
6034
+ startLineNumber: i + 1,
6035
+ originalStartLine: line,
6036
+ contentLines: initialContent ? [initialContent] : [],
6037
+ };
6038
+ foundNewCommitment = true;
6039
+ break;
6040
+ }
6041
+ }
6042
+ // Check if this is a horizontal line (ends any current commitment)
6043
+ const isHorizontalLine = HORIZONTAL_LINE_PATTERN.test(line);
6044
+ if (isHorizontalLine) {
6045
+ // Save the current commitment if it exists
6046
+ if (currentCommitment) {
6047
+ const fullContent = currentCommitment.contentLines.join('\n');
6048
+ commitments.push({
6049
+ type: currentCommitment.type,
6050
+ content: spaceTrim$1.spaceTrim(fullContent),
6051
+ originalLine: currentCommitment.originalStartLine,
6052
+ lineNumber: currentCommitment.startLineNumber,
6053
+ });
6054
+ currentCommitment = null;
6055
+ }
6056
+ // Add horizontal line to non-commitment lines
6057
+ nonCommitmentLines.push(line);
6058
+ continue;
6059
+ }
6060
+ if (!foundNewCommitment) {
6061
+ if (currentCommitment) {
6062
+ // This line belongs to the current commitment
6063
+ currentCommitment.contentLines.push(line);
6064
+ }
6065
+ else {
6066
+ // This line is not part of any commitment
6067
+ nonCommitmentLines.push(line);
6068
+ }
6069
+ }
6070
+ }
6071
+ // Don't forget to save the last commitment if it exists
6072
+ if (currentCommitment) {
6073
+ const fullContent = currentCommitment.contentLines.join('\n');
6074
+ commitments.push({
6075
+ type: currentCommitment.type,
6076
+ content: spaceTrim$1.spaceTrim(fullContent),
6077
+ originalLine: currentCommitment.originalStartLine,
6078
+ lineNumber: currentCommitment.startLineNumber,
6079
+ });
6080
+ }
6081
+ return {
6082
+ agentName,
6083
+ commitments,
6084
+ nonCommitmentLines,
6085
+ };
6086
+ }
6087
+
6088
+ /**
6089
+ * Parses parameters from text using both supported notations:
6090
+ * 1. @Parameter - single word parameter starting with @
6091
+ * 2. {parameterName} or {parameter with multiple words} or {parameterName: description text}
6092
+ *
6093
+ * Both notations represent the same syntax feature - parameters
6094
+ *
6095
+ * @param text - Text to extract parameters from
6096
+ * @returns Array of parsed parameters with unified representation
6097
+ * @public exported from `@promptbook/core`
6098
+ */
6099
+ function parseParameters(text) {
6100
+ const parameters = [];
6101
+ // [🧠] Parameter syntax parsing - unified approach for two different notations of the same syntax feature
6102
+ // The Book language supports parameters in two different notations but they represent the same concept
6103
+ // Extract @Parameter notation (single word parameters starting with @)
6104
+ const atParameterRegex = /@[\w\u00C0-\u017F\u0100-\u024F\u1E00-\u1EFF]+/gim;
6105
+ text.replace(atParameterRegex, (match) => {
6106
+ const parameterName = match.slice(1); // Remove the @ symbol
6107
+ parameters.push({
6108
+ text: match,
6109
+ notation: 'at',
6110
+ name: parameterName,
6111
+ });
6112
+ return match;
6113
+ });
6114
+ // Extract {parameter} notation (parameters in braces)
6115
+ const braceParameterRegex = /\{([^}]+)\}/gim;
6116
+ text.replace(braceParameterRegex, (match, content) => {
6117
+ // Check if the parameter has a description (parameterName: description)
6118
+ const colonIndex = content.indexOf(':');
6119
+ if (colonIndex !== -1) {
6120
+ const name = content.substring(0, colonIndex).trim();
6121
+ const description = content.substring(colonIndex + 1).trim();
6122
+ parameters.push({
6123
+ text: match,
6124
+ notation: 'brace',
6125
+ name,
6126
+ description,
6127
+ });
6128
+ }
6129
+ else {
6130
+ // Simple parameter without description
6131
+ parameters.push({
6132
+ text: match,
6133
+ notation: 'brace',
6134
+ name: content.trim(),
6135
+ });
6136
+ }
6137
+ return match;
6138
+ });
6139
+ // Remove duplicates based on name (keep the first occurrence)
6140
+ const uniqueParameters = parameters.filter((param, index, array) => {
6141
+ return array.findIndex((p) => p.name === param.name) === index;
6142
+ });
6143
+ return uniqueParameters;
6144
+ }
6145
+
6146
+ /**
6147
+ * Parses basic information from agent source
6148
+ *
6149
+ * There are 2 similar functions:
6150
+ * - `parseAgentSource` which is a lightweight parser for agent source, it parses basic information and its purpose is to be quick and synchronous. The commitments there are hardcoded.
6151
+ * - `createAgentModelRequirements` which is an asynchronous function that creates model requirements it applies each commitment one by one and works asynchronously.
6152
+ *
6153
+ * @public exported from `@promptbook/core`
6154
+ */
6155
+ function parseAgentSource(agentSource) {
6156
+ const parseResult = parseAgentSourceWithCommitments(agentSource);
6157
+ // Find PERSONA and META commitments
6158
+ let personaDescription = null;
6159
+ for (const commitment of parseResult.commitments) {
6160
+ if (commitment.type !== 'PERSONA') {
6161
+ continue;
6162
+ }
6163
+ if (personaDescription === null) {
6164
+ personaDescription = '';
6165
+ }
6166
+ else {
6167
+ personaDescription += `\n\n${personaDescription}`;
6168
+ }
6169
+ personaDescription += commitment.content;
6170
+ }
6171
+ let initialMessage = null;
6172
+ for (const commitment of parseResult.commitments) {
6173
+ if (commitment.type !== 'INITIAL MESSAGE') {
6174
+ continue;
6175
+ }
6176
+ // Note: Initial message override logic - later overrides earlier
6177
+ // Or should it append? Usually initial message is just one block.
6178
+ // Let's stick to "later overrides earlier" for simplicity, or just take the last one.
6179
+ initialMessage = commitment.content;
6180
+ }
6181
+ const meta = {};
6182
+ const links = [];
6183
+ for (const commitment of parseResult.commitments) {
6184
+ if (commitment.type === 'META LINK') {
6185
+ const linkValue = spaceTrim__default["default"](commitment.content);
6186
+ links.push(linkValue);
6187
+ meta.link = linkValue;
6188
+ continue;
6189
+ }
6190
+ if (commitment.type === 'META IMAGE') {
6191
+ meta.image = spaceTrim__default["default"](commitment.content);
6192
+ continue;
6193
+ }
6194
+ if (commitment.type === 'META COLOR') {
6195
+ meta.color = spaceTrim__default["default"](commitment.content);
6196
+ continue;
6197
+ }
6198
+ if (commitment.type === 'META FONT') {
6199
+ meta.font = spaceTrim__default["default"](commitment.content);
6200
+ continue;
6201
+ }
6202
+ if (commitment.type !== 'META') {
6203
+ continue;
6204
+ }
6205
+ // Parse META commitments - format is "META TYPE content"
6206
+ const metaTypeRaw = commitment.content.split(' ')[0] || 'NONE';
6207
+ if (metaTypeRaw === 'LINK') {
6208
+ links.push(spaceTrim__default["default"](commitment.content.substring(metaTypeRaw.length)));
6209
+ }
6210
+ const metaType = normalizeTo_camelCase(metaTypeRaw);
6211
+ meta[metaType] = spaceTrim__default["default"](commitment.content.substring(metaTypeRaw.length));
6212
+ }
6213
+ // Generate gravatar fallback if no meta image specified
6214
+ if (!meta.image) {
6215
+ meta.image = generatePlaceholderAgentProfileImageUrl(parseResult.agentName || '!!');
6216
+ }
6217
+ // Generate fullname fallback if no meta fullname specified
6218
+ if (!meta.fullname) {
6219
+ meta.fullname = parseResult.agentName || createDefaultAgentName(agentSource);
6220
+ }
6221
+ // Parse parameters using unified approach - both @Parameter and {parameter} notations
6222
+ // are treated as the same syntax feature with unified representation
6223
+ const parameters = parseParameters(agentSource);
6224
+ const agentHash = computeAgentHash(agentSource);
6225
+ return {
6226
+ agentName: normalizeAgentName(parseResult.agentName || createDefaultAgentName(agentSource)),
6227
+ agentHash,
6228
+ personaDescription,
6229
+ initialMessage,
6230
+ meta,
6231
+ links,
6232
+ parameters,
6233
+ };
6234
+ }
6235
+ /**
6236
+ * TODO: [🕛] Unite `AgentBasicInformation`, `ChatParticipant`, `LlmExecutionTools` + `LlmToolsMetadata`
6237
+ */
6238
+
6239
+ /**
6240
+ * Converts Blob, File or MediaSource to url using URL.createObjectURL
6241
+ *
6242
+ * @public exported from `@promptbook/browser`
6243
+ */
6244
+ class ObjectUrl extends destroyable.Registration {
6245
+ constructor(teardownLogic, src) {
6246
+ super(teardownLogic);
6247
+ this.src = src;
6248
+ }
6249
+ /**
6250
+ * Creates ObjectUrl from multiple input types
6251
+ * Note: DO NOT forget to call destroy() when you are done with it
6252
+ */
6253
+ static from(source, mimeType) {
6254
+ if (typeof source === 'string') {
6255
+ return ObjectUrl.fromString(source, mimeType);
6256
+ }
6257
+ if ((source instanceof Blob || source instanceof File) && source.type !== mimeType) {
6258
+ throw new Error(`Source type ${source.type} does not match given mimeType ${mimeType}`);
6259
+ }
6260
+ return ObjectUrl.fromBlob(source);
6261
+ }
6262
+ /**
6263
+ * Creates ObjectUrl from string
6264
+ * Note: DO NOT forget to call destroy() when you are done with it
6265
+ */
6266
+ static fromString(source, mimeType) {
6267
+ return ObjectUrl.fromBlob(new Blob([source], { type: mimeType }));
6268
+ }
6269
+ /**
6270
+ * Creates ObjectUrl
6271
+ * DO NOT forget to call destroy() when you are done with it
6272
+ */
6273
+ static fromBlob(source) {
6274
+ const src = URL.createObjectURL(source);
6275
+ return new ObjectUrl(() => {
6276
+ URL.revokeObjectURL(src);
6277
+ }, src);
6278
+ }
6279
+ /**
6280
+ * Creates ObjectUrl:
6281
+ * 1) With functionality for Blobs, Files or MediaSources
6282
+ * 2) Just a wrapper for string urls
6283
+ *
6284
+ * DO NOT forget to call destroy() when you are done with it
6285
+ */
6286
+ static fromBlobOrUrl(source) {
6287
+ if (typeof source === 'string' || source instanceof URL /* <- TODO: Probably check isValidUrl */) {
6288
+ return new ObjectUrl(() => {
6289
+ // Note: Nothing to do here
6290
+ }, source.toString());
6291
+ }
6292
+ else {
6293
+ return ObjectUrl.fromBlob(source);
6294
+ }
6295
+ }
6296
+ /**
6297
+ * Gets object url as string
6298
+ * @alias src
6299
+ */
6300
+ get href() {
6301
+ return this.src;
6302
+ }
6303
+ /**
6304
+ * Gets object url as URL object
6305
+ */
6306
+ get url() {
6307
+ return new URL(this.src);
6308
+ }
6309
+ }
6310
+ /**
6311
+ * Note: [🔵] Code in this file should never be published outside of `@promptbook/browser`
6312
+ */
6313
+
6314
+ /**
6315
+ * Download a File in a browser
6316
+ *
6317
+ * Note: `$` is used to indicate that this function is not a pure function - its purpose is to cause a side effect (download a file)
6318
+ *
6319
+ * @public exported from `@promptbook/browser`
6320
+ */
6321
+ async function $induceFileDownload(fileOrBlobOrUrl) {
6322
+ if (!$isRunningInBrowser()) {
6323
+ throw new Error('Function `$induceFileDownload` is available ONLY in browser');
6324
+ }
6325
+ const objectUrl = ObjectUrl.fromBlobOrUrl(fileOrBlobOrUrl);
6326
+ const link = window.document.createElement('a');
6327
+ link.href = objectUrl.href;
6328
+ link.download = fileOrBlobOrUrl.name || 'untitled' /* <- TODO: Add proper extension according to url */;
6329
+ link.click();
6330
+ await objectUrl.destroy();
6331
+ }
6332
+ /**
6333
+ * Note: [🔵] Code in this file should never be published outside of `@promptbook/browser`
6334
+ */
6335
+
6336
+ /**
6337
+ * Download a Book in a browser
6338
+ *
6339
+ * Note: `$` is used to indicate that this function is not a pure function - its purpose is to cause a side effect (download a file)
6340
+ *
6341
+ * @public exported from `@promptbook/browser`
6342
+ */
6343
+ async function $induceBookDownload(book) {
6344
+ if (!$isRunningInBrowser()) {
6345
+ throw new Error('Function `$induceBookDownload` is available ONLY in browser');
6346
+ }
6347
+ const { agentName } = parseAgentSource(book);
6348
+ const bookFile = new File([book], `${titleToName(agentName || 'AI Avatar')}.book`, {
6349
+ type: 'application/json',
6350
+ });
6351
+ return /* not await */ $induceFileDownload(bookFile);
6352
+ }
6353
+ /**
6354
+ * Note: [🔵] Code in this file should never be published outside of `@promptbook/browser`
6355
+ */
6356
+
6357
+ exports.$induceBookDownload = $induceBookDownload;
6358
+ exports.$induceFileDownload = $induceFileDownload;
1970
6359
  exports.$provideScrapersForBrowser = $provideScrapersForBrowser;
1971
6360
  exports.BOOK_LANGUAGE_VERSION = BOOK_LANGUAGE_VERSION;
6361
+ exports.ObjectUrl = ObjectUrl;
1972
6362
  exports.PROMPTBOOK_ENGINE_VERSION = PROMPTBOOK_ENGINE_VERSION;
1973
6363
  exports.SimplePromptInterfaceTools = SimplePromptInterfaceTools;
1974
6364
  exports.getIndexedDbStorage = getIndexedDbStorage;