@promptbook/browser 0.103.0-8 → 0.103.0

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