@promptbook/node 0.103.0-10 → 0.103.0-100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/README.md +92 -62
  2. package/esm/index.es.js +351 -228
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/books/index.d.ts +0 -81
  5. package/esm/typings/servers.d.ts +9 -7
  6. package/esm/typings/src/_packages/browser.index.d.ts +6 -0
  7. package/esm/typings/src/_packages/cli.index.d.ts +4 -0
  8. package/esm/typings/src/_packages/components.index.d.ts +20 -8
  9. package/esm/typings/src/_packages/core.index.d.ts +58 -18
  10. package/esm/typings/src/_packages/node.index.d.ts +2 -2
  11. package/esm/typings/src/_packages/remote-server.index.d.ts +2 -0
  12. package/esm/typings/src/_packages/types.index.d.ts +58 -8
  13. package/esm/typings/src/_packages/utils.index.d.ts +6 -0
  14. package/esm/typings/src/_packages/wizard.index.d.ts +4 -0
  15. package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +19 -5
  16. package/esm/typings/src/book-2.0/agent-source/AgentModelRequirements.d.ts +17 -1
  17. package/esm/typings/src/book-2.0/agent-source/AgentSourceParseResult.d.ts +3 -2
  18. package/esm/typings/src/book-2.0/agent-source/computeAgentHash.d.ts +8 -0
  19. package/esm/typings/src/book-2.0/agent-source/createCommitmentRegex.d.ts +3 -3
  20. package/esm/typings/src/book-2.0/agent-source/createDefaultAgentName.d.ts +8 -0
  21. package/esm/typings/src/book-2.0/agent-source/normalizeAgentName.d.ts +9 -0
  22. package/esm/typings/src/book-2.0/agent-source/padBook.d.ts +18 -0
  23. package/esm/typings/src/book-2.0/agent-source/parseAgentSourceWithCommitments.d.ts +1 -1
  24. package/esm/typings/src/book-2.0/agent-source/string_book.d.ts +3 -0
  25. package/esm/typings/src/book-components/AvatarProfile/AvatarProfile/AvatarProfile.d.ts +6 -1
  26. package/esm/typings/src/book-components/BookEditor/BookEditor.d.ts +77 -7
  27. package/esm/typings/src/book-components/BookEditor/BookEditorActionbar.d.ts +14 -0
  28. package/esm/typings/src/book-components/Chat/AgentChat/AgentChat.d.ts +14 -0
  29. package/esm/typings/src/book-components/Chat/AgentChat/AgentChatProps.d.ts +13 -0
  30. package/esm/typings/src/book-components/Chat/Chat/ChatProps.d.ts +10 -0
  31. package/esm/typings/src/book-components/Chat/LlmChat/LlmChatProps.d.ts +5 -0
  32. package/esm/typings/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +15 -0
  33. package/esm/typings/src/book-components/Chat/MockedChat/MockedChat.d.ts +5 -0
  34. package/esm/typings/src/book-components/Chat/save/_common/ChatSaveFormatDefinition.d.ts +1 -1
  35. package/esm/typings/src/book-components/Chat/save/html/htmlSaveFormatDefinition.d.ts +1 -0
  36. package/esm/typings/src/book-components/Chat/save/pdf/pdfSaveFormatDefinition.d.ts +4 -0
  37. package/esm/typings/src/book-components/Chat/types/ChatParticipant.d.ts +1 -1
  38. package/esm/typings/src/book-components/PromptbookAgent/PromptbookAgent.d.ts +29 -0
  39. package/esm/typings/src/book-components/Qr/BrandedQrCode.d.ts +18 -0
  40. package/esm/typings/src/book-components/Qr/GenericQrCode.d.ts +10 -0
  41. package/esm/typings/src/book-components/Qr/PromptbookQrCode.d.ts +18 -0
  42. package/esm/typings/src/book-components/Qr/useQrCode.d.ts +15 -0
  43. package/esm/typings/src/book-components/_common/Dropdown/Dropdown.d.ts +15 -0
  44. package/esm/typings/src/book-components/_common/HamburgerMenu/HamburgerMenu.d.ts +12 -0
  45. package/esm/typings/src/book-components/_common/Modal/Modal.d.ts +2 -2
  46. package/esm/typings/src/book-components/_common/Tooltip/Tooltip.d.ts +47 -0
  47. package/esm/typings/src/book-components/icons/AboutIcon.d.ts +9 -0
  48. package/esm/typings/src/book-components/icons/CloseIcon.d.ts +4 -8
  49. package/esm/typings/src/book-components/icons/DownloadIcon.d.ts +9 -0
  50. package/esm/typings/src/book-components/icons/ExitFullscreenIcon.d.ts +7 -0
  51. package/esm/typings/src/book-components/icons/FullscreenIcon.d.ts +7 -0
  52. package/esm/typings/src/book-components/icons/MenuIcon.d.ts +12 -0
  53. package/esm/typings/src/book-components/icons/MicIcon.d.ts +8 -0
  54. package/esm/typings/src/cli/cli-commands/_boilerplate.d.ts +2 -1
  55. package/esm/typings/src/cli/cli-commands/about.d.ts +3 -1
  56. package/esm/typings/src/cli/cli-commands/hello.d.ts +2 -1
  57. package/esm/typings/src/cli/cli-commands/list-models.d.ts +2 -1
  58. package/esm/typings/src/cli/cli-commands/list-scrapers.d.ts +2 -1
  59. package/esm/typings/src/cli/cli-commands/login.d.ts +2 -1
  60. package/esm/typings/src/cli/cli-commands/make.d.ts +2 -1
  61. package/esm/typings/src/cli/cli-commands/prettify.d.ts +2 -1
  62. package/esm/typings/src/cli/cli-commands/run.d.ts +2 -1
  63. package/esm/typings/src/cli/cli-commands/{start-server.d.ts → start-agents-server.d.ts} +3 -2
  64. package/esm/typings/src/cli/cli-commands/start-pipelines-server.d.ts +15 -0
  65. package/esm/typings/src/cli/cli-commands/test-command.d.ts +2 -1
  66. package/esm/typings/src/cli/common/$addGlobalOptionsToCommand.d.ts +2 -1
  67. package/esm/typings/src/collection/agent-collection/AgentCollection.d.ts +12 -0
  68. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +75 -0
  69. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabaseOptions.d.ts +10 -0
  70. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +154 -0
  71. package/esm/typings/src/collection/{PipelineCollection.d.ts → pipeline-collection/PipelineCollection.d.ts} +7 -3
  72. package/esm/typings/src/collection/{SimplePipelineCollection.d.ts → pipeline-collection/SimplePipelineCollection.d.ts} +5 -5
  73. package/esm/typings/src/collection/{constructors/createCollectionFromDirectory.d.ts → pipeline-collection/constructors/createPipelineCollectionFromDirectory.d.ts} +8 -11
  74. package/esm/typings/src/collection/pipeline-collection/constructors/createPipelineCollectionFromJson.d.ts +13 -0
  75. package/esm/typings/src/collection/{constructors/createCollectionFromPromise.d.ts → pipeline-collection/constructors/createPipelineCollectionFromPromise.d.ts} +6 -5
  76. package/esm/typings/src/collection/pipeline-collection/constructors/createPipelineCollectionFromPromise.test.d.ts +1 -0
  77. package/esm/typings/src/collection/{constructors/createCollectionFromUrl.d.ts → pipeline-collection/constructors/createPipelineCollectionFromUrl.d.ts} +3 -3
  78. package/esm/typings/src/collection/{constructors/createSubcollection.d.ts → pipeline-collection/constructors/createPipelineSubcollection.d.ts} +3 -3
  79. package/esm/typings/src/collection/pipeline-collection/pipelineCollectionToJson.d.ts +13 -0
  80. package/esm/typings/src/commands/_common/types/CommandParser.d.ts +4 -5
  81. package/esm/typings/src/{book-2.0/commitments → commitments}/ACTION/ACTION.d.ts +5 -1
  82. package/esm/typings/src/commitments/CLOSED/CLOSED.d.ts +35 -0
  83. package/esm/typings/src/commitments/COMPONENT/COMPONENT.d.ts +28 -0
  84. package/esm/typings/src/{book-2.0/commitments → commitments}/DELETE/DELETE.d.ts +5 -1
  85. package/esm/typings/src/{book-2.0/commitments → commitments}/FORMAT/FORMAT.d.ts +5 -1
  86. package/esm/typings/src/commitments/FROM/FROM.d.ts +34 -0
  87. package/esm/typings/src/{book-2.0/commitments → commitments}/GOAL/GOAL.d.ts +5 -1
  88. package/esm/typings/src/{book-2.0/commitments → commitments}/KNOWLEDGE/KNOWLEDGE.d.ts +5 -5
  89. package/esm/typings/src/commitments/LANGUAGE/LANGUAGE.d.ts +35 -0
  90. package/esm/typings/src/{book-2.0/commitments → commitments}/MEMORY/MEMORY.d.ts +5 -1
  91. package/esm/typings/src/commitments/MESSAGE/AgentMessageCommitmentDefinition.d.ts +32 -0
  92. package/esm/typings/src/commitments/MESSAGE/InitialMessageCommitmentDefinition.d.ts +32 -0
  93. package/esm/typings/src/{book-2.0/commitments → commitments}/MESSAGE/MESSAGE.d.ts +5 -1
  94. package/esm/typings/src/commitments/MESSAGE/UserMessageCommitmentDefinition.d.ts +32 -0
  95. package/esm/typings/src/{book-2.0/commitments → commitments}/META/META.d.ts +5 -1
  96. package/esm/typings/src/commitments/META_COLOR/META_COLOR.d.ts +48 -0
  97. package/esm/typings/src/commitments/META_FONT/META_FONT.d.ts +42 -0
  98. package/esm/typings/src/{book-2.0/commitments → commitments}/META_IMAGE/META_IMAGE.d.ts +5 -1
  99. package/esm/typings/src/{book-2.0/commitments → commitments}/META_LINK/META_LINK.d.ts +5 -1
  100. package/esm/typings/src/{book-2.0/commitments → commitments}/MODEL/MODEL.d.ts +5 -1
  101. package/esm/typings/src/{book-2.0/commitments → commitments}/NOTE/NOTE.d.ts +5 -1
  102. package/esm/typings/src/commitments/OPEN/OPEN.d.ts +35 -0
  103. package/esm/typings/src/{book-2.0/commitments → commitments}/PERSONA/PERSONA.d.ts +5 -1
  104. package/esm/typings/src/{book-2.0/commitments → commitments}/RULE/RULE.d.ts +5 -1
  105. package/esm/typings/src/{book-2.0/commitments → commitments}/SAMPLE/SAMPLE.d.ts +5 -1
  106. package/esm/typings/src/{book-2.0/commitments → commitments}/SCENARIO/SCENARIO.d.ts +5 -1
  107. package/esm/typings/src/{book-2.0/commitments → commitments}/STYLE/STYLE.d.ts +5 -1
  108. package/esm/typings/src/commitments/USE/USE.d.ts +53 -0
  109. package/esm/typings/src/commitments/USE_BROWSER/USE_BROWSER.d.ts +38 -0
  110. package/esm/typings/src/commitments/USE_BROWSER/USE_BROWSER.test.d.ts +1 -0
  111. package/esm/typings/src/commitments/USE_MCP/USE_MCP.d.ts +37 -0
  112. package/esm/typings/src/commitments/USE_SEARCH_ENGINE/USE_SEARCH_ENGINE.d.ts +38 -0
  113. package/esm/typings/src/{book-2.0/commitments → commitments}/_base/BaseCommitmentDefinition.d.ts +8 -2
  114. package/esm/typings/src/{book-2.0/commitments → commitments}/_base/CommitmentDefinition.d.ts +6 -1
  115. package/esm/typings/src/{book-2.0/commitments → commitments}/_base/NotYetImplementedCommitmentDefinition.d.ts +5 -1
  116. package/esm/typings/src/{book-2.0/commitments → commitments}/_base/createEmptyAgentModelRequirements.d.ts +1 -1
  117. package/esm/typings/src/commitments/index.d.ts +93 -0
  118. package/esm/typings/src/config.d.ts +24 -3
  119. package/esm/typings/src/conversion/validation/validatePipeline.d.ts +2 -0
  120. package/esm/typings/src/errors/0-index.d.ts +6 -0
  121. package/esm/typings/src/errors/DatabaseError.d.ts +12 -0
  122. package/esm/typings/src/errors/NotAllowed.d.ts +9 -0
  123. package/esm/typings/src/errors/WrappedError.d.ts +2 -2
  124. package/esm/typings/src/execution/AvailableModel.d.ts +1 -0
  125. package/esm/typings/src/execution/Executables.d.ts +3 -0
  126. package/esm/typings/src/execution/ExecutionTask.d.ts +12 -3
  127. package/esm/typings/src/execution/ExecutionTools.d.ts +5 -0
  128. package/esm/typings/src/execution/FilesystemTools.d.ts +1 -1
  129. package/esm/typings/src/execution/LlmExecutionTools.d.ts +21 -1
  130. package/esm/typings/src/execution/createPipelineExecutor/10-executePipeline.d.ts +5 -0
  131. package/esm/typings/src/execution/createPipelineExecutor/20-executeTask.d.ts +5 -0
  132. package/esm/typings/src/execution/createPipelineExecutor/30-executeFormatSubvalues.d.ts +5 -0
  133. package/esm/typings/src/execution/createPipelineExecutor/40-executeAttempts.d.ts +5 -0
  134. package/esm/typings/src/execution/utils/usage-constants.d.ts +4 -124
  135. package/esm/typings/src/execution/utils/validatePromptResult.d.ts +2 -0
  136. package/esm/typings/src/high-level-abstractions/_common/HighLevelAbstraction.d.ts +2 -1
  137. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForWizardOrCli.d.ts +2 -2
  138. package/esm/typings/src/llm-providers/_common/register/$registeredLlmToolsMessage.d.ts +2 -1
  139. package/esm/typings/src/llm-providers/_common/register/LlmToolsMetadata.d.ts +1 -1
  140. package/esm/typings/src/llm-providers/_common/utils/assertUniqueModels.d.ts +12 -0
  141. package/esm/typings/src/llm-providers/_multiple/getSingleLlmExecutionTools.d.ts +1 -0
  142. package/esm/typings/src/llm-providers/_multiple/joinLlmExecutionTools.d.ts +1 -0
  143. package/esm/typings/src/llm-providers/agent/Agent.d.ts +70 -0
  144. package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +26 -4
  145. package/esm/typings/src/llm-providers/agent/AgentOptions.d.ts +19 -0
  146. package/esm/typings/src/llm-providers/agent/CreateAgentLlmExecutionToolsOptions.d.ts +17 -0
  147. package/esm/typings/src/llm-providers/agent/RemoteAgent.d.ts +50 -0
  148. package/esm/typings/src/llm-providers/agent/RemoteAgentOptions.d.ts +11 -0
  149. package/esm/typings/src/llm-providers/agent/createAgentLlmExecutionTools.d.ts +1 -19
  150. package/esm/typings/src/llm-providers/anthropic-claude/anthropic-claude-models.d.ts +1 -1
  151. package/esm/typings/src/llm-providers/google/google-models.d.ts +1 -1
  152. package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionTools.d.ts +60 -2
  153. package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionToolsOptions.d.ts +7 -1
  154. package/esm/typings/src/llm-providers/openai/openai-models.d.ts +1 -1
  155. package/esm/typings/src/llm-providers/openai/openai-models.test.d.ts +4 -0
  156. package/esm/typings/src/other/templates/getTemplatesPipelineCollection.d.ts +1 -1
  157. package/esm/typings/src/pipeline/validatePipelineString.d.ts +2 -0
  158. package/esm/typings/src/playground/permanent/_boilerplate.d.ts +5 -0
  159. package/esm/typings/src/playground/permanent/agent-with-browser-playground.d.ts +5 -0
  160. package/esm/typings/src/prepare/PrepareAndScrapeOptions.d.ts +1 -0
  161. package/esm/typings/src/remote-server/startAgentServer.d.ts +26 -0
  162. package/esm/typings/src/remote-server/startRemoteServer.d.ts +4 -1
  163. package/esm/typings/src/remote-server/types/RemoteServerOptions.d.ts +3 -8
  164. package/esm/typings/src/scrapers/_boilerplate/createBoilerplateScraper.d.ts +1 -12
  165. package/esm/typings/src/scrapers/_boilerplate/register-metadata.d.ts +1 -9
  166. package/esm/typings/src/scrapers/document/createDocumentScraper.d.ts +1 -12
  167. package/esm/typings/src/scrapers/document/register-metadata.d.ts +1 -9
  168. package/esm/typings/src/scrapers/document-legacy/createLegacyDocumentScraper.d.ts +1 -12
  169. package/esm/typings/src/scrapers/document-legacy/register-metadata.d.ts +1 -9
  170. package/esm/typings/src/scrapers/markdown/createMarkdownScraper.d.ts +1 -12
  171. package/esm/typings/src/scrapers/markdown/register-metadata.d.ts +1 -9
  172. package/esm/typings/src/scrapers/markitdown/createMarkitdownScraper.d.ts +1 -12
  173. package/esm/typings/src/scrapers/markitdown/register-metadata.d.ts +1 -9
  174. package/esm/typings/src/scrapers/pdf/createPdfScraper.d.ts +1 -12
  175. package/esm/typings/src/scrapers/pdf/register-metadata.d.ts +1 -9
  176. package/esm/typings/src/scrapers/website/createWebsiteScraper.d.ts +1 -12
  177. package/esm/typings/src/scrapers/website/register-metadata.d.ts +1 -9
  178. package/esm/typings/src/storage/_common/PromptbookStorage.d.ts +1 -0
  179. package/esm/typings/src/storage/env-storage/$EnvStorage.d.ts +2 -1
  180. package/esm/typings/src/transpilers/_common/BookTranspiler.d.ts +33 -0
  181. package/esm/typings/src/transpilers/_common/BookTranspilerOptions.d.ts +18 -0
  182. package/esm/typings/src/transpilers/_common/register/$bookTranspilersRegister.d.ts +15 -0
  183. package/esm/typings/src/transpilers/formatted-book-in-markdown/FormattedBookInMarkdownTranspiler.d.ts +16 -0
  184. package/esm/typings/src/transpilers/formatted-book-in-markdown/register.d.ts +15 -0
  185. package/esm/typings/src/transpilers/openai-sdk/OpenAiSdkTranspiler.d.ts +16 -0
  186. package/esm/typings/src/transpilers/openai-sdk/OpenAiSdkTranspiler.test.d.ts +1 -0
  187. package/esm/typings/src/transpilers/openai-sdk/playground/playground.d.ts +5 -0
  188. package/esm/typings/src/transpilers/openai-sdk/register.d.ts +15 -0
  189. package/esm/typings/src/types/LlmCall.d.ts +20 -0
  190. package/esm/typings/src/types/Updatable.d.ts +19 -0
  191. package/esm/typings/src/types/typeAliases.d.ts +32 -2
  192. package/esm/typings/src/utils/color/$randomColor.d.ts +1 -0
  193. package/esm/typings/src/utils/color/Color.d.ts +15 -0
  194. package/esm/typings/src/utils/color/Color.test.d.ts +1 -0
  195. package/esm/typings/src/utils/color/css-colors.d.ts +1 -0
  196. package/esm/typings/src/utils/color/internal-utils/checkChannelValue.d.ts +0 -3
  197. package/esm/typings/src/utils/color/operators/darken.d.ts +1 -1
  198. package/esm/typings/src/utils/color/operators/grayscale.d.ts +1 -1
  199. package/esm/typings/src/utils/color/operators/lighten.d.ts +1 -1
  200. package/esm/typings/src/utils/color/operators/mixWithColor.d.ts +1 -1
  201. package/esm/typings/src/utils/color/operators/saturate.d.ts +1 -1
  202. package/esm/typings/src/utils/environment/$detectRuntimeEnvironment.d.ts +16 -0
  203. package/esm/typings/src/utils/environment/$getGlobalScope.d.ts +2 -2
  204. package/esm/typings/src/utils/execCommand/$execCommand.d.ts +2 -1
  205. package/esm/typings/src/utils/execCommand/$execCommands.d.ts +2 -1
  206. package/esm/typings/src/utils/files/$induceBookDownload.d.ts +13 -0
  207. package/esm/typings/src/utils/files/$induceFileDownload.d.ts +13 -0
  208. package/esm/typings/src/utils/files/ObjectUrl.d.ts +46 -0
  209. package/esm/typings/src/utils/files/listAllFiles.d.ts +2 -3
  210. package/esm/typings/src/utils/misc/aboutPromptbookInformation.d.ts +27 -0
  211. package/esm/typings/src/utils/misc/computeHash.d.ts +11 -0
  212. package/esm/typings/src/utils/misc/computeHash.test.d.ts +1 -0
  213. package/esm/typings/src/utils/misc/xAboutPromptbookInformation.d.ts +13 -0
  214. package/esm/typings/src/utils/normalization/normalize-to-kebab-case.d.ts +2 -0
  215. package/esm/typings/src/utils/normalization/normalizeMessageText.d.ts +9 -0
  216. package/esm/typings/src/utils/normalization/normalizeMessageText.test.d.ts +1 -0
  217. package/esm/typings/src/utils/normalization/normalizeTo_PascalCase.d.ts +3 -0
  218. package/esm/typings/src/utils/normalization/normalizeTo_camelCase.d.ts +2 -0
  219. package/esm/typings/src/utils/normalization/titleToName.d.ts +2 -0
  220. package/esm/typings/src/utils/organization/$sideEffect.d.ts +2 -2
  221. package/esm/typings/src/utils/organization/$side_effect.d.ts +7 -0
  222. package/esm/typings/src/utils/organization/TODO_USE.d.ts +2 -2
  223. package/esm/typings/src/utils/organization/keepUnused.d.ts +2 -2
  224. package/esm/typings/src/utils/organization/preserve.d.ts +3 -3
  225. package/esm/typings/src/utils/organization/really_any.d.ts +7 -0
  226. package/esm/typings/src/utils/random/$generateBookBoilerplate.d.ts +25 -0
  227. package/esm/typings/src/utils/random/$randomAgentPersona.d.ts +9 -0
  228. package/esm/typings/src/utils/random/$randomFullnameWithColor.d.ts +13 -0
  229. package/esm/typings/src/utils/random/$randomItem.d.ts +9 -0
  230. package/esm/typings/src/utils/random/$randomSeed.d.ts +3 -0
  231. package/esm/typings/src/utils/random/$randomToken.d.ts +2 -0
  232. package/esm/typings/src/utils/serialization/$deepFreeze.d.ts +2 -1
  233. package/esm/typings/src/utils/serialization/asSerializable.d.ts +2 -2
  234. package/esm/typings/src/utils/serialization/serializeToPromptbookJavascript.d.ts +2 -2
  235. package/esm/typings/src/utils/validators/parameterName/validateParameterName.d.ts +2 -0
  236. package/esm/typings/src/version.d.ts +1 -1
  237. package/esm/typings/src/wizard/$getCompiledBook.d.ts +1 -2
  238. package/package.json +7 -7
  239. package/umd/index.umd.js +359 -236
  240. package/umd/index.umd.js.map +1 -1
  241. package/esm/typings/src/book-2.0/commitments/index.d.ts +0 -60
  242. package/esm/typings/src/book-components/BookEditor/config.d.ts +0 -11
  243. package/esm/typings/src/book-components/Chat/utils/renderMarkdown.d.ts +0 -21
  244. package/esm/typings/src/collection/collectionToJson.d.ts +0 -13
  245. package/esm/typings/src/collection/constructors/createCollectionFromJson.d.ts +0 -13
  246. /package/esm/typings/src/{book-components/Chat/utils/renderMarkdown.test.d.ts → book-2.0/agent-source/computeAgentHash.test.d.ts} +0 -0
  247. /package/esm/typings/src/{collection/constructors/createCollectionFromDirectory.test.d.ts → book-2.0/agent-source/normalizeAgentName.test.d.ts} +0 -0
  248. /package/esm/typings/src/{collection/constructors/createCollectionFromJson.test.d.ts → book-components/Chat/AgentChat/AgentChat.test.d.ts} +0 -0
  249. /package/esm/typings/src/collection/{constructors/createCollectionFromPromise.test.d.ts → pipeline-collection/constructors/createPipelineCollectionFromDirectory.test.d.ts} +0 -0
  250. /package/esm/typings/src/{commands/_common/parseCommand.test.d.ts → collection/pipeline-collection/constructors/createPipelineCollectionFromJson.test.d.ts} +0 -0
  251. /package/esm/typings/src/collection/{collectionToJson.test.d.ts → pipeline-collection/pipelineCollectionToJson.test.d.ts} +0 -0
  252. /package/esm/typings/src/{book-2.0/commitments → commitments}/_base/BookCommitment.d.ts +0 -0
  253. /package/esm/typings/src/{book-2.0/commitments → commitments}/_base/ParsedCommitment.d.ts +0 -0
package/esm/index.es.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import colors from 'colors';
2
- import { stat, access, constants, readFile, writeFile, readdir, mkdir, unlink } from 'fs/promises';
2
+ import { stat, access, constants, readFile, writeFile, readdir, mkdir, watch, unlink } from 'fs/promises';
3
3
  import { basename, join, dirname, isAbsolute, relative } from 'path';
4
- import spaceTrim, { spaceTrim as spaceTrim$1 } from 'spacetrim';
4
+ import spaceTrim$2, { spaceTrim as spaceTrim$1 } from 'spacetrim';
5
5
  import JSZip from 'jszip';
6
6
  import { randomBytes } from 'crypto';
7
7
  import { Subject } from 'rxjs';
@@ -21,19 +21,30 @@ import * as dotenv from 'dotenv';
21
21
  * @generated
22
22
  * @see https://github.com/webgptorg/book
23
23
  */
24
- const BOOK_LANGUAGE_VERSION = '1.0.0';
24
+ const BOOK_LANGUAGE_VERSION = '2.0.0';
25
25
  /**
26
26
  * The version of the Promptbook engine
27
27
  *
28
28
  * @generated
29
29
  * @see https://github.com/webgptorg/promptbook
30
30
  */
31
- const PROMPTBOOK_ENGINE_VERSION = '0.103.0-10';
31
+ const PROMPTBOOK_ENGINE_VERSION = '0.103.0-100';
32
32
  /**
33
33
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
34
34
  * Note: [💞] Ignore a discrepancy between file name and entity name
35
35
  */
36
36
 
37
+ /**
38
+ * Trims string from all 4 sides
39
+ *
40
+ * Note: This is a re-exported function from the `spacetrim` package which is
41
+ * Developed by same author @hejny as this package
42
+ *
43
+ * @public exported from `@promptbook/utils`
44
+ * @see https://github.com/hejny/spacetrim#usage
45
+ */
46
+ const spaceTrim = spaceTrim$1;
47
+
37
48
  /**
38
49
  * @private util of `@promptbook/color`
39
50
  * @de
@@ -82,6 +93,7 @@ function take(initialValue) {
82
93
  * @public exported from `@promptbook/color`
83
94
  */
84
95
  const CSS_COLORS = {
96
+ promptbook: '#79EAFD',
85
97
  transparent: 'rgba(0,0,0,0)',
86
98
  aliceblue: '#f0f8ff',
87
99
  antiquewhite: '#faebd7',
@@ -263,9 +275,6 @@ function checkChannelValue(channelName, value) {
263
275
  throw new Error(`${channelName} channel is greater than 255, it is ${value}`);
264
276
  }
265
277
  }
266
- /**
267
- * TODO: [🧠][🚓] Is/which combination it better to use asserts/check, validate or is utility function?
268
- */
269
278
 
270
279
  /**
271
280
  * Color object represents an RGB color with alpha channel
@@ -300,6 +309,28 @@ class Color {
300
309
  throw new Error(`Can not create color from given object`);
301
310
  }
302
311
  }
312
+ /**
313
+ * Creates a new Color instance from miscellaneous formats
314
+ * It just does not throw error when it fails, it returns PROMPTBOOK_COLOR instead
315
+ *
316
+ * @param color
317
+ * @returns Color object
318
+ */
319
+ static fromSafe(color) {
320
+ try {
321
+ return Color.from(color);
322
+ }
323
+ catch (error) {
324
+ // <- Note: Can not use `assertsError(error)` here because it causes circular dependency
325
+ console.warn(spaceTrim((block) => `
326
+ Color.fromSafe error:
327
+ ${block(error.message)}
328
+
329
+ Returning default PROMPTBOOK_COLOR.
330
+ `));
331
+ return Color.fromString('promptbook');
332
+ }
333
+ }
303
334
  /**
304
335
  * Creates a new Color instance from miscellaneous string formats
305
336
  *
@@ -367,6 +398,9 @@ class Color {
367
398
  if (hex.length === 3) {
368
399
  return Color.fromHex3(hex);
369
400
  }
401
+ if (hex.length === 4) {
402
+ return Color.fromHex4(hex);
403
+ }
370
404
  if (hex.length === 6) {
371
405
  return Color.fromHex6(hex);
372
406
  }
@@ -387,6 +421,19 @@ class Color {
387
421
  const b = parseInt(hex.substr(2, 1), 16) * 16;
388
422
  return take(new Color(r, g, b));
389
423
  }
424
+ /**
425
+ * Creates a new Color instance from color in hex format with 4 digits (with alpha channel)
426
+ *
427
+ * @param color in hex for example `09df`
428
+ * @returns Color object
429
+ */
430
+ static fromHex4(hex) {
431
+ const r = parseInt(hex.substr(0, 1), 16) * 16;
432
+ const g = parseInt(hex.substr(1, 1), 16) * 16;
433
+ const b = parseInt(hex.substr(2, 1), 16) * 16;
434
+ const a = parseInt(hex.substr(3, 1), 16) * 16;
435
+ return take(new Color(r, g, b, a));
436
+ }
390
437
  /**
391
438
  * Creates a new Color instance from color in hex format with 6 color digits (without alpha channel)
392
439
  *
@@ -577,7 +624,8 @@ class Color {
577
624
  * @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
578
625
  */
579
626
  static isHexColorString(value) {
580
- return typeof value === 'string' && /^#(?:[0-9a-fA-F]{3}){1,2}$/.test(value);
627
+ return (typeof value === 'string' &&
628
+ /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value));
581
629
  }
582
630
  /**
583
631
  * Creates new Color object
@@ -692,6 +740,23 @@ class Color {
692
740
  * TODO: Maybe connect with textures
693
741
  */
694
742
 
743
+ /**
744
+ * Makes color transformer which returns a grayscale version of the color
745
+ *
746
+ * @param amount from 0 to 1
747
+ *
748
+ * @public exported from `@promptbook/color`
749
+ */
750
+ function grayscale(amount) {
751
+ return ({ red, green, blue, alpha }) => {
752
+ const average = (red + green + blue) / 3;
753
+ red = Math.round(average * amount + red * (1 - amount));
754
+ green = Math.round(average * amount + green * (1 - amount));
755
+ blue = Math.round(average * amount + blue * (1 - amount));
756
+ return Color.fromValues(red, green, blue, alpha);
757
+ };
758
+ }
759
+
695
760
  /**
696
761
  * Converts HSL values to RGB values
697
762
  *
@@ -807,102 +872,6 @@ function lighten(amount) {
807
872
  * TODO: Maybe implement by mix+hsl
808
873
  */
809
874
 
810
- /**
811
- * Calculates distance between two colors
812
- *
813
- * @param color1 first color
814
- * @param color2 second color
815
- *
816
- * Note: This function is inefficient. Use colorDistanceSquared instead if possible.
817
- *
818
- * @public exported from `@promptbook/color`
819
- */
820
- /**
821
- * Calculates distance between two colors without square root
822
- *
823
- * @param color1 first color
824
- * @param color2 second color
825
- *
826
- * @public exported from `@promptbook/color`
827
- */
828
- function colorDistanceSquared(color1, color2) {
829
- const rmean = (color1.red + color2.red) / 2;
830
- const r = color1.red - color2.red;
831
- const g = color1.green - color2.green;
832
- const b = color1.blue - color2.blue;
833
- const weightR = 2 + rmean / 256;
834
- const weightG = 4.0;
835
- const weightB = 2 + (255 - rmean) / 256;
836
- const distance = weightR * r * r + weightG * g * g + weightB * b * b;
837
- return distance;
838
- }
839
-
840
- /**
841
- * Makes color transformer which finds the nearest color from the given list
842
- *
843
- * @param colors array of colors to choose from
844
- *
845
- * @public exported from `@promptbook/color`
846
- */
847
- function nearest(...colors) {
848
- return (color) => {
849
- const distances = colors.map((c) => colorDistanceSquared(c, color));
850
- const minDistance = Math.min(...distances);
851
- const minIndex = distances.indexOf(minDistance);
852
- const nearestColor = colors[minIndex];
853
- return nearestColor;
854
- };
855
- }
856
-
857
- /**
858
- * Color transformer which returns the negative color
859
- *
860
- * @public exported from `@promptbook/color`
861
- */
862
- function negative(color) {
863
- const r = 255 - color.red;
864
- const g = 255 - color.green;
865
- const b = 255 - color.blue;
866
- return Color.fromValues(r, g, b, color.alpha);
867
- }
868
-
869
- /**
870
- * Makes color transformer which finds the furthest color from the given list
871
- *
872
- * @param colors array of colors to choose from
873
- *
874
- * @public exported from `@promptbook/color`
875
- */
876
- function furthest(...colors) {
877
- return (color) => {
878
- const furthestColor = negative(nearest(...colors.map(negative))(color));
879
- return furthestColor;
880
- };
881
- }
882
- /**
883
- * Makes color transformer which finds the best text color (black or white) for the given background color
884
- *
885
- * @public exported from `@promptbook/color`
886
- */
887
- furthest(Color.get('white'), Color.from('black'));
888
-
889
- /**
890
- * Makes color transformer which returns a grayscale version of the color
891
- *
892
- * @param amount from 0 to 1
893
- *
894
- * @public exported from `@promptbook/color`
895
- */
896
- function grayscale(amount) {
897
- return ({ red, green, blue, alpha }) => {
898
- const average = (red + green + blue) / 3;
899
- red = Math.round(average * amount + red * (1 - amount));
900
- green = Math.round(average * amount + green * (1 - amount));
901
- blue = Math.round(average * amount + blue * (1 - amount));
902
- return Color.fromValues(red, green, blue, alpha);
903
- };
904
- }
905
-
906
875
  /**
907
876
  * Makes color transformer which saturate the given color
908
877
  *
@@ -971,16 +940,32 @@ const ADMIN_GITHUB_NAME = 'hejny';
971
940
  *
972
941
  * @public exported from `@promptbook/core`
973
942
  */
974
- const PROMPTBOOK_COLOR = Color.fromHex('#79EAFD');
975
- // <- TODO: [🧠] Using `Color` here increases the package size approx 3kb, maybe remove it
943
+ const PROMPTBOOK_COLOR = Color.fromString('promptbook');
944
+ // <- TODO: [🧠][🈵] Using `Color` here increases the package size approx 3kb, maybe remove it
945
+ /**
946
+ * Colors for syntax highlighting in the `<BookEditor/>`
947
+ *
948
+ * TODO: [🗽] Unite branding and make single place for it
949
+ *
950
+ * @public exported from `@promptbook/core`
951
+ */
952
+ ({
953
+ TITLE: Color.fromHex('#244EA8'),
954
+ LINE: Color.fromHex('#eeeeee'),
955
+ SEPARATOR: Color.fromHex('#cccccc'),
956
+ COMMITMENT: Color.fromHex('#DA0F78'),
957
+ PARAMETER: Color.fromHex('#8e44ad'),
958
+ });
959
+ // <- TODO: [🧠][🈵] Using `Color` here increases the package size approx 3kb, maybe remove it
976
960
  /**
977
- * Dark color of the Promptbook
961
+ * Chat color of the Promptbook (in chat)
978
962
  *
979
963
  * TODO: [🗽] Unite branding and make single place for it
980
964
  *
981
965
  * @public exported from `@promptbook/core`
982
966
  */
983
967
  PROMPTBOOK_COLOR.then(lighten(0.1)).then(saturate(0.9)).then(grayscale(0.9));
968
+ // <- TODO: [🧠][🈵] Using `Color` and `lighten`, `saturate`,... here increases the package size approx 3kb, maybe remove it
984
969
  /**
985
970
  * Color of the user (in chat)
986
971
  *
@@ -989,6 +974,7 @@ PROMPTBOOK_COLOR.then(lighten(0.1)).then(saturate(0.9)).then(grayscale(0.9));
989
974
  * @public exported from `@promptbook/core`
990
975
  */
991
976
  Color.fromHex('#1D4ED8');
977
+ // <- TODO: [🧠][🈵] Using `Color` here increases the package size approx 3kb, maybe remove it
992
978
  /**
993
979
  * When the title is not provided, the default title is used
994
980
  *
@@ -1087,7 +1073,7 @@ const DEFAULT_MAX_PARALLEL_COUNT = 5; // <- TODO: [🤹‍♂️]
1087
1073
  * @public exported from `@promptbook/core`
1088
1074
  */
1089
1075
  const DEFAULT_MAX_EXECUTION_ATTEMPTS = 7; // <- TODO: [🤹‍♂️]
1090
- // <- TODO: [🕝] Make also `BOOKS_DIRNAME_ALTERNATIVES`
1076
+ // <- TODO: [🕝] Make also `AGENTS_DIRNAME_ALTERNATIVES`
1091
1077
  // TODO: Just `.promptbook` in config, hardcode subfolders like `download-cache` or `execution-cache`
1092
1078
  /**
1093
1079
  * Where to store the temporary downloads
@@ -1115,7 +1101,7 @@ TODO: [🌃]
1115
1101
  ex-port const WIZARD_APP_ID: string_app_id = 'wizard';
1116
1102
  */
1117
1103
  /**
1118
- * The name of the builded pipeline collection made by CLI `ptbk make` and for lookup in `createCollectionFromDirectory`
1104
+ * The name of the builded pipeline collection made by CLI `ptbk make` and for lookup in `createPipelineCollectionFromDirectory`
1119
1105
  *
1120
1106
  * @public exported from `@promptbook/core`
1121
1107
  */
@@ -1179,7 +1165,7 @@ true);
1179
1165
  function getErrorReportUrl(error) {
1180
1166
  const report = {
1181
1167
  title: `🐜 Error report from ${NAME}`,
1182
- body: spaceTrim((block) => `
1168
+ body: spaceTrim$2((block) => `
1183
1169
 
1184
1170
 
1185
1171
  \`${error.name || 'Error'}\` has occurred in the [${NAME}], please look into it @${ADMIN_GITHUB_NAME}.
@@ -1252,7 +1238,7 @@ function jsonParse(value) {
1252
1238
  }
1253
1239
  else if (typeof value !== 'string') {
1254
1240
  console.error('Can not parse JSON from non-string value.', { text: value });
1255
- throw new Error(spaceTrim(`
1241
+ throw new Error(spaceTrim$2(`
1256
1242
  Can not parse JSON from non-string value.
1257
1243
 
1258
1244
  The value type: ${typeof value}
@@ -1266,7 +1252,7 @@ function jsonParse(value) {
1266
1252
  if (!(error instanceof Error)) {
1267
1253
  throw error;
1268
1254
  }
1269
- throw new Error(spaceTrim((block) => `
1255
+ throw new Error(spaceTrim$2((block) => `
1270
1256
  ${block(error.message)}
1271
1257
 
1272
1258
  The expected JSON text:
@@ -1415,7 +1401,7 @@ function checkSerializableAsJson(options) {
1415
1401
  }
1416
1402
  else if (typeof value === 'object') {
1417
1403
  if (value instanceof Date) {
1418
- throw new UnexpectedError(spaceTrim((block) => `
1404
+ throw new UnexpectedError(spaceTrim$2((block) => `
1419
1405
  \`${name}\` is Date
1420
1406
 
1421
1407
  Use \`string_date_iso8601\` instead
@@ -1434,7 +1420,7 @@ function checkSerializableAsJson(options) {
1434
1420
  throw new UnexpectedError(`${name} is RegExp`);
1435
1421
  }
1436
1422
  else if (value instanceof Error) {
1437
- throw new UnexpectedError(spaceTrim((block) => `
1423
+ throw new UnexpectedError(spaceTrim$2((block) => `
1438
1424
  \`${name}\` is unserialized Error
1439
1425
 
1440
1426
  Use function \`serializeError\`
@@ -1457,7 +1443,7 @@ function checkSerializableAsJson(options) {
1457
1443
  }
1458
1444
  catch (error) {
1459
1445
  assertsError(error);
1460
- throw new UnexpectedError(spaceTrim((block) => `
1446
+ throw new UnexpectedError(spaceTrim$2((block) => `
1461
1447
  \`${name}\` is not serializable
1462
1448
 
1463
1449
  ${block(error.stack || error.message)}
@@ -1489,7 +1475,7 @@ function checkSerializableAsJson(options) {
1489
1475
  }
1490
1476
  }
1491
1477
  else {
1492
- throw new UnexpectedError(spaceTrim((block) => `
1478
+ throw new UnexpectedError(spaceTrim$2((block) => `
1493
1479
  \`${name}\` is unknown type
1494
1480
 
1495
1481
  Additional message for \`${name}\`:
@@ -1519,7 +1505,7 @@ function deepClone(objectValue) {
1519
1505
  TODO: [🧠] Is there a better implementation?
1520
1506
  > const propertyNames = Object.getOwnPropertyNames(objectValue);
1521
1507
  > for (const propertyName of propertyNames) {
1522
- > const value = (objectValue as really_any)[propertyName];
1508
+ > const value = (objectValue as chococake)[propertyName];
1523
1509
  > if (value && typeof value === 'object') {
1524
1510
  > deepClone(value);
1525
1511
  > }
@@ -1770,6 +1756,8 @@ function isValidPipelineUrl(url) {
1770
1756
  * - if it is valid json
1771
1757
  * - if it is meaningful
1772
1758
  *
1759
+ * Note: [🔂] This function is idempotent.
1760
+ *
1773
1761
  * @param pipeline valid or invalid PipelineJson
1774
1762
  * @returns the same pipeline if it is logically valid
1775
1763
  * @throws {PipelineLogicError} on logical error in the pipeline
@@ -2080,7 +2068,7 @@ async function loadArchive(filePath, fs) {
2080
2068
  * Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
2081
2069
  */
2082
2070
 
2083
- var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book",formfactorName:"GENERIC",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",resultingParameterName:"knowledgePieces",dependentParameterNames:["knowledgeContent"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Knowledge from Markdown\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book`\n- INPUT PARAMETER `{knowledgeContent}` Markdown document content\n- OUTPUT PARAMETER `{knowledgePieces}` The knowledge JSON object\n\n## Knowledge\n\n<!-- TODO: [🍆] -FORMAT JSON -->\n\n```markdown\nYou are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}\n```\n\n`-> {knowledgePieces}`\n"}],sourceFile:"./books/prepare-knowledge-from-markdown.book"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.book",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",resultingParameterName:"keywords",dependentParameterNames:["knowledgePieceContent"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Keywords\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-keywords.book`\n- INPUT PARAMETER `{knowledgePieceContent}` The content\n- OUTPUT PARAMETER `{keywords}` Keywords separated by comma\n\n## Knowledge\n\n<!-- TODO: [🍆] -FORMAT JSON -->\n\n```markdown\nYou are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}\n```\n\n`-> {keywords}`\n"}],sourceFile:"./books/prepare-knowledge-keywords.book"},{title:"Prepare Knowledge-piece Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.book",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"knowledge",title:"Knowledge",content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Knowledge-piece Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-title.book`\n- INPUT PARAMETER `{knowledgePieceContent}` The content\n- OUTPUT PARAMETER `{title}` The title of the document\n\n## Knowledge\n\n- EXPECT MIN 1 WORD\n- EXPECT MAX 8 WORDS\n\n```markdown\nYou are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-knowledge-title.book"},{title:"Prepare Persona",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.book",formfactorName:"GENERIC",parameters:[{name:"availableModels",description:"List of available model names together with their descriptions as JSON",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelsRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"make-model-requirements",title:"Make modelRequirements",content:"You are an experienced AI engineer, you need to find the best models for virtual assistants:\n\n## Example\n\n```json\n[\n {\n \"modelName\": \"gpt-4o\",\n \"systemMessage\": \"You are experienced AI engineer and helpful assistant.\",\n \"temperature\": 0.7\n },\n {\n \"modelName\": \"claude-3-5-sonnet\",\n \"systemMessage\": \"You are a friendly and knowledgeable chatbot.\",\n \"temperature\": 0.5\n }\n]\n```\n\n## Instructions\n\n- Your output format is JSON array\n- Sort best-fitting models first\n- Omit any models that are not suitable\n- Write just the JSON, no other text should be present\n- Array contain items with following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nHere are the available models:\n\n```json\n{availableModels}\n```\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",resultingParameterName:"modelsRequirements",format:"JSON",dependentParameterNames:["availableModels","personaDescription"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Persona\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-persona.book`\n- INPUT PARAMETER `{availableModels}` List of available model names together with their descriptions as JSON\n- INPUT PARAMETER `{personaDescription}` Description of the persona\n- OUTPUT PARAMETER `{modelsRequirements}` Specific requirements for the model\n\n## Make modelRequirements\n\n- FORMAT JSON\n\n```markdown\nYou are an experienced AI engineer, you need to find the best models for virtual assistants:\n\n## Example\n\n\\`\\`\\`json\n[\n {\n \"modelName\": \"gpt-4o\",\n \"systemMessage\": \"You are experienced AI engineer and helpful assistant.\",\n \"temperature\": 0.7\n },\n {\n \"modelName\": \"claude-3-5-sonnet\",\n \"systemMessage\": \"You are a friendly and knowledgeable chatbot.\",\n \"temperature\": 0.5\n }\n]\n\\`\\`\\`\n\n## Instructions\n\n- Your output format is JSON array\n- Sort best-fitting models first\n- Omit any models that are not suitable\n- Write just the JSON, no other text should be present\n- Array contain items with following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nHere are the available models:\n\n\\`\\`\\`json\n{availableModels}\n\\`\\`\\`\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}\n```\n\n`-> {modelsRequirements}`\n"}],sourceFile:"./books/prepare-persona.book"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-title.book",formfactorName:"GENERIC",parameters:[{name:"book",description:"The book to prepare the title for",isInput:true,isOutput:false},{name:"title",description:"Best title for the book",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"make-title",title:"Make title",content:"Make best title for given text which describes the workflow:\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\n- Title starts with emoticon\n- Title should not mention the input and output of the workflow but the main purpose of the workflow\n _For example, not \"✍ Convert Knowledge-piece to title\" but \"✍ Title\"_\n\n## The workflow\n\n> {book}",resultingParameterName:"title",expectations:{words:{min:1,max:8},lines:{min:1,max:1}},dependentParameterNames:["book"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-title.book`\n- INPUT PARAMETER `{book}` The book to prepare the title for\n- OUTPUT PARAMETER `{title}` Best title for the book\n\n## Make title\n\n- EXPECT MIN 1 Word\n- EXPECT MAX 8 Words\n- EXPECT EXACTLY 1 Line\n\n```markdown\nMake best title for given text which describes the workflow:\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\n- Title starts with emoticon\n- Title should not mention the input and output of the workflow but the main purpose of the workflow\n _For example, not \"✍ Convert Knowledge-piece to title\" but \"✍ Title\"_\n\n## The workflow\n\n> {book}\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-title.book"},{title:"📊 Curriculum Audit",pipelineUrl:"https://promptbook.studio/promptbook//examples/lsvp-asistent.book",formfactorName:"GENERIC",parameters:[{name:"result",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"prompt",title:"Prompt",content:"Asistent pro LŠVP\n\nPERSONA Jsi asistent pro RVP Lyceum v rámci Národního pedagogického institutu České Republiky\nMETA IMAGE https://edulk.cz/getFile/id:475818/type:large/02%20zna%C4%8Dka%20npi.jpg\nRULE Pokud jsi nejsi jistý, napiš nevím\nKNOWLEDGE ./241129_Lyceum_final.pdf\nCONTEXT Obecně dokážeš řešit libovolné ŠVP, aktuálně řešíš {Školní vzdělávací program LYCEUM}\nRULE Z {Porovnání RVP a ŠVP - postup} je nejdůležitější fáze 3\nKNOWLEDGE {Školní vzdělávací program LYCEUM} ./ŠVP Lyceum - Finance v digitální době.pdf\nKNOWLEDGE @Slovník\n\n**Interní slovník - RVP/ŠVP**\n\n**RVP**\n\nRámcový vzdělávací program pro obor vzdělání Lyceum je dokument na národní úrovni, který formuluje požadavky na školní vzdělávací programy ve formě především očekávaných výsledků učení, kterých mají žáci absolvováním tohoto programu na dané škole dosáhnout.\n\n**ŠVP**\n\nŠkolní vzdělávací program pro obor vzdělání Lyceum je dokument každé jednotlivé školy, který popisuje v jakých vyučovacích předmětech/ vzdělávacích modulech a v jakých ročnících budou požadované očekávané výsledky učení naplněny. Zároveň formuluje další očekávané výsledky učení, které naplňují disponibilní část vyučovacího času určeného RVP pro tento obor vzdělání.\n\n**Očekávaný výsledek učení (OVU)**\n\nVyjadřuje jednotlivý požadavek na to, co mají žáci umět na konci vzdělávacího programu, tzn. jejich požadované kompetence. Je vyjádřen formulací, která je uvozena činnostním slovesem a dále obsahuje předmět této činnosti. Formulace je konkretizována resp. doplněna zpravidla formou odrážek vymezením dílčích znalostí, dovedností, postojů, jejichž splnění je předpokladem dosažení OVU jako celku.\n\n_Příklad:_\n\n<div class=\"joplin-table-wrapper\"><table><tbody><tr><th><p><strong>Žák/žákyně řídí realizaci jednoduchého projektu</strong></p></th></tr><tr><td><ul><li>naplánuje aktivity projektu</li></ul></td></tr><tr><td><ul><li>navrhne rozpočet projektu vzhledem k navrženým aktivitám</li></ul></td></tr><tr><td><ul><li>stanoví základní ukazatele a sleduje jejich naplňování</li></ul></td></tr><tr><td><ul><li>vede projektový tým</li></ul></td></tr><tr><td><ul><li>uvede, jak by řešil krizové situace v projektu</li></ul></td></tr><tr><td><ul><li>vyhodnotí úspěšnost projektu</li></ul></td></tr></tbody></table></div>\n\n**Vzdělávací oblasti**\n\nOčekávané výsledky učení jsou v **_RVP členěny do 4 vzdělávacích oblastí_**, které tvoří společný všeobecně vzdělávací základ:\n\n- Osobnostní rozvoj, vzdělávání ke zdraví, bezpečí a produktivnímu pracovnímu životu (kariéře)\n- Komunikační a jazykové vzdělávání\n- Aplikované vzdělávání STEM (Science, Technology, Engeneering, Math), tj. přírodní vědy, informatika, technika, matematika\n- Prakticky orientované vzdělávání společenskovědní a humanitní\n\nKaždá vzdělávací oblast se dále člení na okruhy, v jejichž rámci jsou OVU samostatně číslované.\n\n<div class=\"joplin-table-wrapper\"><table><tbody><tr><th rowspan=\"21\"><ul><li>Prakticky orientované vzdělávání společenskovědní a humanitní</li></ul></th><th rowspan=\"21\"><p><strong>Člověk, ekonomie a podnikání</strong></p></th><th rowspan=\"7\"><p><strong>1</strong></p></th><th><p><strong>zpracuje podklady související s podnikáním</strong></p></th></tr><tr><td><p>připraví podnikatelský záměr</p></td></tr><tr><td><p>sestaví zakladatelský rozpočet</p></td></tr><tr><td><p>zkalkuluje cenu zboží nebo služby</p></td></tr><tr><td><p>vysvětlí na příkladu základní povinnosti podnikatele vůči státu a zaměstnancům</p></td></tr><tr><td><p>vede daňovou evidenci</p></td></tr><tr><td><p>vysvětlí na příkladech etiku v podnikání</p></td></tr><tr><td rowspan=\"7\"><p><strong>2</strong></p></td><td><p><strong>řídí realizaci jednoduchého projektu</strong></p></td></tr><tr><td><p>naplánuje aktivity projektu</p></td></tr><tr><td><p>navrhne rozpočet projektu vzhledem k navrženým aktivitám</p></td></tr><tr><td><p>stanoví základní ukazatele a sleduje jejich naplňování</p></td></tr><tr><td><p>vede projektový tým</p></td></tr><tr><td><p>uvede, jak by řešil krizové situace v projektu</p></td></tr><tr><td><p>vyhodnotí úspěšnost projektu</p></td></tr><tr><td rowspan=\"7\"><p><strong>3</strong></p></td><td><p><strong>aplikuje ekonomické teorie v osobním a profesním životě</strong></p></td></tr><tr><td><p>vysvětlí základní ekonomické otázky</p></td></tr><tr><td><p>vysvětí stanovení rovnovážné ceny na dokonalém i nedokonalém trhu</p></td></tr><tr><td><p>charakterizuje výrobní faktory a vysvětlí hranici produkčních možností a náklady obětované příležitosti</p></td></tr><tr><td><p>uvede nejdůležitější makroekonomické pojmy a vliv jejich výše na kvalitu života a podnikání v daném státě</p></td></tr><tr><td><p>vysvětlí podstatu inflace a její důsledky na finanční situaci obyvatel a na příkladu ukáže jak se bránit jejím nepříznivým důsledkům</p></td></tr><tr><td><p>uvede hlavní výhody a nevýhody mezinárodního obchodu a vliv ochranářských opatření na ekonomickou situaci dané země</p></td></tr><tr><td></td><td></td><td><p><strong>4</strong></p></td><td><p>Atd.</p></td></tr></tbody></table></div>\n\n**Vyučovací předmět / vzdělávací modul**\n\nOčekávané výsledky učení jsou v **ŠVP** členěny do vyučovacích předmětů nebo vzdělávacích modulů, které jsou dále zařazeny do jednoho nebo více ročníků 4letého studia. Vyučovací předmět / vzdělávací modul tvoří vyučovací jednotku, kde jsou očekávané výsledky učení dále rozpracovány pro potřeby výuky podle následující šablony\n\n| **A. VSTUPNÍ ČÁST** |\n| --- |\n| **1\\. Název** |\n| **2\\. Kód** (kódy by měly být navázány na obory vzdělání a výsledky učení) |\n| **2a) Kategorie vzdělání** - v případě, že nebude součástí kódu |\n| **3\\. Typ vyučovací jednotky** (modul, předmět, stáž apod.) |\n| **4\\. Délka** (počet hodin - dělitelný čtyřmi (optimální modul 16, 32 hodin = týden výuky) |\n| **5\\. Platnost** (datum, od kterého platí) |\n| **6\\. Vstupní předpoklady** (vymezení požadované úrovně vstupních vědomostí a dovedností, které jsou předpokladem úspěšného studia) |\n| |\n| **B. JÁDRO VYUČOVACÍ JEDNOTKY** |\n| **1\\. Charakteristika** (stručná anotace popisující obecné cíle a pojetí) |\n| **2\\. Očekávané výsledky učení a jejich indikátory (převzaté z RVP nebo dále konkretizované)** |\n| **3\\. Podpora rozvoje klíčových kompetencí a základních gramotností** (které klíčové kompetence jsou v rozvíjeny) |\n| **4\\. Obsah vzdělávání** (rozpis učiva) |\n| **5\\. Vzdělávací strategie** (strategie výuky, resp. učební činnosti žáků, které jsou doporučené pro dosažení výsledků) |\n| |\n| **C. VÝSTUPNÍ ČÁST** |\n| **1\\. Způsob ověřování dosažených výsledků** (ve vazbě na jednotlivé výsledky učení) |\n| **2\\. Kritéria hodnocení** (co znamená splnění výsledků učení, kdy je splněna celá vyučovací jednotka, kritéria pro známky, příp. procentuální, slovní hodnocení) |\n| **3\\. Doporučená studijní literatura, odkazy na ilustrační zdroje** |\n| **4\\. Poznámky** |\n\n**Soulad OVU RVP a ŠVP**\n\nTento soulad je předmětem zjišťování. Soulad nastává, jestliže jsou očekávané výsledky učení z jednotlivých vzdělávacích oblastí RVP **obsaženy** ve vyučovacích předmětech/ vzdělávacích modulech ŠVP jednotlivých škol, tzn. že v ŠVP se objevuje jejich formulace buď v doslovném nebo podobném znění v jednom nebo více vyučovacích předmětech/ vzdělávacích modulech.\n\n_Příklad souladu:_\n\nRVP ŠVP - komunikace a marketing (SŠ obchodní Č.\n\n| **2** | **řídí realizaci jednoduchého projektu** |\n| --- | --- |\n| naplánuje aktivity projektu |\n| navrhne rozpočet projektu vzhledem k navrženým aktivitám |\n| stanoví základní ukazatele a sleduje jejich naplňování |\n| vede projektový tým |\n| uvede, jak by řešil krizové situace v projektu |\n| vyhodnotí úspěšnost projektu |\n\nKNOWLEDGE {Porovnání RVP a ŠVP - postup}\n\n\n# AUDITNÍ PROTOKOL ŠVP-RVP\n\n# (POPIS KONTROLNÍHO ALGORITMU)\n\nMetodika je určena pro **Kvantifikaci Shody** školního vzdělávacího programu (ŠVP) s Rámcovým vzdělávacím programem (RVP).\n\n## FÁZE 1: VALIDACE DOKUMENTACE\n\n**Cíl:** Ověřit platnost, aktuálnost a strukturu zdrojových dokumentů.\n\n- **RVP Verifikace:** Otevřít aktuální verzi RVP (např. RVP ZV/G/SOŠ).\n- **Typová shoda:** Ověřit, že RVP se vztahuje k danému typu školy.\n- **ŠVP Dimenze:** Identifikovat a izolovat relevantní části ŠVP: Profil absolventa, Klíčové kompetence (KK), Vzdělávací oblasti (VO), případně Učební plán (UP).\n- **Verzování:** Potvrdit, že obě verze (RVP a ŠVP) jsou nejnovější a platné (včetně dodatků RVP).\n\n## FÁZE 2: DATABÁZOVÉ MAPOVÁNÍ VÝSTUPŮ (MASTER MATICE)\n\n**Cíl:** Vytvořit systémovou databázi pro křížové porovnání všech povinných komponent RVP se ŠVP.\n\n- **Dekompozice RVP:** Rozložit RVP na základní povinné komponenty: Klíčové kompetence, Vzdělávací oblasti a obory, Očekávané výstupy (OVU), Průřezová témata (PT).\n- **Přiřazovací mapa:** Vytvořit hlavní kontrolní matici (Master Matice) pro záznam vazeb.\n\n| Oblast RVP | Výstup RVP (OVU) | Odpovídající Část ŠVP (Předmět/Ročník) | Konkrétní Tématický Celek v ŠVP | Stav Shody (Protokol) |\n| --- | --- | --- | --- | --- |\n| ... | ... | ... | ... | ... |\n| --- | --- | --- | --- | --- |\n\n## FÁZE 3: ALGORITMICKÁ KONTROLA POKRYTÍ A HLOUBKY\n\n**Cíl:** Posoudit, zda každý povinný výstup RVP je adekvátně reflektován v obsahu ŠVP, a přidělit bodovou hodnotu pro kvantifikaci.\n\n- **Audit OVU:** Projít každý jednotlivý Očekávaný výstup (OVU) z RVP.\n- **Kódování stavu a bodování:** U každého OVU v matici označit stav pokrytí dle následujícího schématu:\n\n| Kód (Protokol) | Popis (Kvalitativní zjištění) | Bodová hodnota (Kvantifikace) |\n| --- | --- | --- |\n| ✅ | Plná shoda (Výstup pokryt v plném rozsahu, odpovídající úrovni RVP) | 1,0 |\n| --- | --- | --- |\n| ⚠️ | Částečná shoda (Formální pokrytí, omezený rozsah, chybná návaznost) | 0,5 |\n| --- | --- | --- |\n| ❌ | Absence (Výstup zcela chybí v obsahu ŠVP) | 0,0 |\n| --- | --- | --- |\n\n- **Defektologie ŠVP:** Identifikovat a zaznamenat deficity ŠVP: Chybějící výstupy (❌), Sémantické překryvy, Přetížení obsahu.\n- **Kvalitativní posun:** Ověřit, zda je formulace výstupů v ŠVP **aktivní, měřitelná a v souladu** s úrovní RVP.\n\n## FÁZE 4: STRUKTURÁLNÍ VERIFIKACE NÁVAZNOSTI (VERTIKÁLA/HORIZONTÁLA)\n\n**Cíl:** Zkontrolovat logickou posloupnost a provázanost učiva v rámci ŠVP.\n\n- **Vertikální Kontrola:** Ověřit posloupnost OVU a učiva uvnitř jednoho předmětu/oblasti (postup od jednodušších ke složitějším konceptům napříč ročníky).\n- **Horizontální Kontrola:** Zkontrolovat logické provázání napříč vzdělávacími oblastmi a předměty (např. fyzika ↔ matematika).\n- **PT Integrace:** Audit reálné integrace Průřezových témat (PT) do konkrétních částí obsahu, metod a projektů.\n\n## FÁZE 5: ANALÝZA ŠKOLNÍ PROFILACE A ROZŠÍŘENÍ RVP\n\n**Cíl:** Validovat, že profilace školy je **v souladu** s RVP a nejedná se o **rozpor**.\n\n- **Nekonfliktnost:** Porovnat definovaný Profil absolventa školy s Klíčovými kompetencemi RVP. Profil ŠVP musí RVP rozvíjet, nikoli mu odporovat.\n- **Modularita:** Zkontrolovat, zda volitelné předměty a rozšiřující moduly logicky navazují na vzdělávací oblasti RVP.\n- **Implementace specializace:** Popisně uvést, jak je školní profilace (např. STEM zaměření, projektová výuka) integrována do OVU a kompetencí definovaných RVP.\n\n## FÁZE 6: GENERÁTOR ZÁVĚREČNÉ ZPRÁVY A KVANTIFIKACE\n\n**Cíl:** Syntetizovat výsledky, kvantifikovat soulad a generovat závazné návrhy na korekce.\n\n### 6.1 Kvantifikace Souladu\n\nVypočítat Index shody (IS) na základě bodového hodnocení (Fáze 3):\n\n### 6.2 Interpretace Indexu Shody (IS)\n\nKlasifikace souladu pro standardizované vyhodnocení:\n\n| Interval IS | Klasifikace souladu | Popis |\n| --- | --- | --- |\n| 95-100 % | Výborný soulad | ŠVP plně odpovídá RVP, pouze stylistické nebo formální rozdíly. |\n| --- | --- | --- |\n| 85-94 % | Dobrá shoda | ŠVP pokrývá všechny klíčové výstupy, menší korekce nutné. |\n| --- | --- | --- |\n| 70-84 % | Částečná shoda | Významné nedostatky v některých oblastech, nutná revize obsahu. |\n| --- | --- | --- |\n| < 70 % | Kritická neshoda | ŠVP neplní rámcové požadavky, ohrožuje legislativní soulad. |\n| --- | --- | --- |\n\n### 6.3 Doplňkové Indexy\n\nVypočítat následující doplňkové indexy pro detailní kvalitativní analýzu:\n\n- **Index kompetenčního souladu (IKS):** Poměr pokrytí klíčových kompetencí RVP v ŠVP.\n- **Index průřezové integrace (IPI):** Míra reálné integrace průřezových témat do výuky.\n- **Index hloubky pokrytí (IHP):** Procento výstupů, které jsou v ŠVP rozvedeny na konkrétní výukové cíle (měřitelné, aktivní formulace).\n- **Index profilové rozšiřitelnosti (IPR):** Kolik rozšiřujících nebo profilových výstupů přesahuje rámec RVP, aniž by narušily jeho strukturu.\n\n### 6.4 Vizuální výstupy\n\nZajistit generování následujících vizualizací pro Závěrečnou zprávu:\n\n- Graf pokrytí po vzdělávacích oblastech (Sloupcový graf IS pro VO).\n- Pavoukový diagram Klíčových kompetencí (RVP vs. ŠVP).\n- Mapa defektů (Vizualizace ❌ a ⚠️ výstupů).\n\n### 6.5 Struktura Závěrečné Zprávy\n\nZpráva musí být strukturována dle standardizovaného formátu:\n\n| Oddíl | Obsah |\n| --- | --- |\n| A. Identifikace | Název školy, IZO, typ školy, datum revize, zpracovatel, verze ŠVP a RVP. |\n| --- | --- |\n| B. Shrnutí výsledků | Celkový Index Shody (IS), hlavní závěry a doporučení. |\n| --- | --- |\n| C. Kvantitativní analýza | Přehled IS v % dle kategorií OVU / VO / kompetencí. |\n| --- | --- |\n| D. Kvalitativní analýza | Slovní zhodnocení kvality souladu (formulace, obtížnost, integrace PT). |\n| --- | --- |\n| E. Rizikové oblasti | Přehled nalezených defektů (chybějící OVU, přetížení, formální shoda). |\n| --- | --- |\n| F. Návrhy opatření (Korekční plán) | Přesné návrhy změn - **Co, Kde, Kdo** má upravit, včetně termínu. |\n| --- | --- |\n| G. Přílohy | Master Matice (Fáze 2-3), revizní tabulka, výstupní grafy a metriky. |\n| --- | --- |\n\n\n\n\n.",resultingParameterName:"result",dependentParameterNames:[]}],personas:[],preparations:[{id:1,promptbookVersion:"0.103.0-9",usage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"Asistent pro LŠVP\n\nPERSONA Jsi asistent pro RVP Lyceum v rámci Národního pedagogického institutu České Republiky\nMETA IMAGE https://edulk.cz/getFile/id:475818/type:large/02%20zna%C4%8Dka%20npi.jpg\nRULE Pokud jsi nejsi jistý, napiš nevím\nKNOWLEDGE ./241129_Lyceum_final.pdf\nCONTEXT Obecně dokážeš řešit libovolné ŠVP, aktuálně řešíš {Školní vzdělávací program LYCEUM}\nRULE Z {Porovnání RVP a ŠVP - postup} je nejdůležitější fáze 3\nKNOWLEDGE {Školní vzdělávací program LYCEUM} ./ŠVP Lyceum - Finance v digitální době.pdf\nKNOWLEDGE @Slovník\n\n**Interní slovník - RVP/ŠVP**\n\n**RVP**\n\nRámcový vzdělávací program pro obor vzdělání Lyceum je dokument na národní úrovni, který formuluje požadavky na školní vzdělávací programy ve formě především očekávaných výsledků učení, kterých mají žáci absolvováním tohoto programu na dané škole dosáhnout.\n\n**ŠVP**\n\nŠkolní vzdělávací program pro obor vzdělání Lyceum je dokument každé jednotlivé školy, který popisuje v jakých vyučovacích předmětech/ vzdělávacích modulech a v jakých ročnících budou požadované očekávané výsledky učení naplněny. Zároveň formuluje další očekávané výsledky učení, které naplňují disponibilní část vyučovacího času určeného RVP pro tento obor vzdělání.\n\n**Očekávaný výsledek učení (OVU)**\n\nVyjadřuje jednotlivý požadavek na to, co mají žáci umět na konci vzdělávacího programu, tzn. jejich požadované kompetence. Je vyjádřen formulací, která je uvozena činnostním slovesem a dále obsahuje předmět této činnosti. Formulace je konkretizována resp. doplněna zpravidla formou odrážek vymezením dílčích znalostí, dovedností, postojů, jejichž splnění je předpokladem dosažení OVU jako celku.\n\n_Příklad:_\n\n<div class=\"joplin-table-wrapper\"><table><tbody><tr><th><p><strong>Žák/žákyně řídí realizaci jednoduchého projektu</strong></p></th></tr><tr><td><ul><li>naplánuje aktivity projektu</li></ul></td></tr><tr><td><ul><li>navrhne rozpočet projektu vzhledem k navrženým aktivitám</li></ul></td></tr><tr><td><ul><li>stanoví základní ukazatele a sleduje jejich naplňování</li></ul></td></tr><tr><td><ul><li>vede projektový tým</li></ul></td></tr><tr><td><ul><li>uvede, jak by řešil krizové situace v projektu</li></ul></td></tr><tr><td><ul><li>vyhodnotí úspěšnost projektu</li></ul></td></tr></tbody></table></div>\n\n**Vzdělávací oblasti**\n\nOčekávané výsledky učení jsou v **_RVP členěny do 4 vzdělávacích oblastí_**, které tvoří společný všeobecně vzdělávací základ:\n\n- Osobnostní rozvoj, vzdělávání ke zdraví, bezpečí a produktivnímu pracovnímu životu (kariéře)\n- Komunikační a jazykové vzdělávání\n- Aplikované vzdělávání STEM (Science, Technology, Engeneering, Math), tj. přírodní vědy, informatika, technika, matematika\n- Prakticky orientované vzdělávání společenskovědní a humanitní\n\nKaždá vzdělávací oblast se dále člení na okruhy, v jejichž rámci jsou OVU samostatně číslované.\n\n<div class=\"joplin-table-wrapper\"><table><tbody><tr><th rowspan=\"21\"><ul><li>Prakticky orientované vzdělávání společenskovědní a humanitní</li></ul></th><th rowspan=\"21\"><p><strong>Člověk, ekonomie a podnikání</strong></p></th><th rowspan=\"7\"><p><strong>1</strong></p></th><th><p><strong>zpracuje podklady související s podnikáním</strong></p></th></tr><tr><td><p>připraví podnikatelský záměr</p></td></tr><tr><td><p>sestaví zakladatelský rozpočet</p></td></tr><tr><td><p>zkalkuluje cenu zboží nebo služby</p></td></tr><tr><td><p>vysvětlí na příkladu základní povinnosti podnikatele vůči státu a zaměstnancům</p></td></tr><tr><td><p>vede daňovou evidenci</p></td></tr><tr><td><p>vysvětlí na příkladech etiku v podnikání</p></td></tr><tr><td rowspan=\"7\"><p><strong>2</strong></p></td><td><p><strong>řídí realizaci jednoduchého projektu</strong></p></td></tr><tr><td><p>naplánuje aktivity projektu</p></td></tr><tr><td><p>navrhne rozpočet projektu vzhledem k navrženým aktivitám</p></td></tr><tr><td><p>stanoví základní ukazatele a sleduje jejich naplňování</p></td></tr><tr><td><p>vede projektový tým</p></td></tr><tr><td><p>uvede, jak by řešil krizové situace v projektu</p></td></tr><tr><td><p>vyhodnotí úspěšnost projektu</p></td></tr><tr><td rowspan=\"7\"><p><strong>3</strong></p></td><td><p><strong>aplikuje ekonomické teorie v osobním a profesním životě</strong></p></td></tr><tr><td><p>vysvětlí základní ekonomické otázky</p></td></tr><tr><td><p>vysvětí stanovení rovnovážné ceny na dokonalém i nedokonalém trhu</p></td></tr><tr><td><p>charakterizuje výrobní faktory a vysvětlí hranici produkčních možností a náklady obětované příležitosti</p></td></tr><tr><td><p>uvede nejdůležitější makroekonomické pojmy a vliv jejich výše na kvalitu života a podnikání v daném státě</p></td></tr><tr><td><p>vysvětlí podstatu inflace a její důsledky na finanční situaci obyvatel a na příkladu ukáže jak se bránit jejím nepříznivým důsledkům</p></td></tr><tr><td><p>uvede hlavní výhody a nevýhody mezinárodního obchodu a vliv ochranářských opatření na ekonomickou situaci dané země</p></td></tr><tr><td></td><td></td><td><p><strong>4</strong></p></td><td><p>Atd.</p></td></tr></tbody></table></div>\n\n**Vyučovací předmět / vzdělávací modul**\n\nOčekávané výsledky učení jsou v **ŠVP** členěny do vyučovacích předmětů nebo vzdělávacích modulů, které jsou dále zařazeny do jednoho nebo více ročníků 4letého studia. Vyučovací předmět / vzdělávací modul tvoří vyučovací jednotku, kde jsou očekávané výsledky učení dále rozpracovány pro potřeby výuky podle následující šablony\n\n| **A. VSTUPNÍ ČÁST** |\n| --- |\n| **1\\. Název** |\n| **2\\. Kód** (kódy by měly být navázány na obory vzdělání a výsledky učení) |\n| **2a) Kategorie vzdělání** - v případě, že nebude součástí kódu |\n| **3\\. Typ vyučovací jednotky** (modul, předmět, stáž apod.) |\n| **4\\. Délka** (počet hodin - dělitelný čtyřmi (optimální modul 16, 32 hodin = týden výuky) |\n| **5\\. Platnost** (datum, od kterého platí) |\n| **6\\. Vstupní předpoklady** (vymezení požadované úrovně vstupních vědomostí a dovedností, které jsou předpokladem úspěšného studia) |\n| |\n| **B. JÁDRO VYUČOVACÍ JEDNOTKY** |\n| **1\\. Charakteristika** (stručná anotace popisující obecné cíle a pojetí) |\n| **2\\. Očekávané výsledky učení a jejich indikátory (převzaté z RVP nebo dále konkretizované)** |\n| **3\\. Podpora rozvoje klíčových kompetencí a základních gramotností** (které klíčové kompetence jsou v rozvíjeny) |\n| **4\\. Obsah vzdělávání** (rozpis učiva) |\n| **5\\. Vzdělávací strategie** (strategie výuky, resp. učební činnosti žáků, které jsou doporučené pro dosažení výsledků) |\n| |\n| **C. VÝSTUPNÍ ČÁST** |\n| **1\\. Způsob ověřování dosažených výsledků** (ve vazbě na jednotlivé výsledky učení) |\n| **2\\. Kritéria hodnocení** (co znamená splnění výsledků učení, kdy je splněna celá vyučovací jednotka, kritéria pro známky, příp. procentuální, slovní hodnocení) |\n| **3\\. Doporučená studijní literatura, odkazy na ilustrační zdroje** |\n| **4\\. Poznámky** |\n\n**Soulad OVU RVP a ŠVP**\n\nTento soulad je předmětem zjišťování. Soulad nastává, jestliže jsou očekávané výsledky učení z jednotlivých vzdělávacích oblastí RVP **obsaženy** ve vyučovacích předmětech/ vzdělávacích modulech ŠVP jednotlivých škol, tzn. že v ŠVP se objevuje jejich formulace buď v doslovném nebo podobném znění v jednom nebo více vyučovacích předmětech/ vzdělávacích modulech.\n\n_Příklad souladu:_\n\nRVP ŠVP - komunikace a marketing (SŠ obchodní Č.\n\n| **2** | **řídí realizaci jednoduchého projektu** |\n| --- | --- |\n| naplánuje aktivity projektu |\n| navrhne rozpočet projektu vzhledem k navrženým aktivitám |\n| stanoví základní ukazatele a sleduje jejich naplňování |\n| vede projektový tým |\n| uvede, jak by řešil krizové situace v projektu |\n| vyhodnotí úspěšnost projektu |\n\nKNOWLEDGE {Porovnání RVP a ŠVP - postup}\n\n\n# AUDITNÍ PROTOKOL ŠVP-RVP\n\n# (POPIS KONTROLNÍHO ALGORITMU)\n\nMetodika je určena pro **Kvantifikaci Shody** školního vzdělávacího programu (ŠVP) s Rámcovým vzdělávacím programem (RVP).\n\n## FÁZE 1: VALIDACE DOKUMENTACE\n\n**Cíl:** Ověřit platnost, aktuálnost a strukturu zdrojových dokumentů.\n\n- **RVP Verifikace:** Otevřít aktuální verzi RVP (např. RVP ZV/G/SOŠ).\n- **Typová shoda:** Ověřit, že RVP se vztahuje k danému typu školy.\n- **ŠVP Dimenze:** Identifikovat a izolovat relevantní části ŠVP: Profil absolventa, Klíčové kompetence (KK), Vzdělávací oblasti (VO), případně Učební plán (UP).\n- **Verzování:** Potvrdit, že obě verze (RVP a ŠVP) jsou nejnovější a platné (včetně dodatků RVP).\n\n## FÁZE 2: DATABÁZOVÉ MAPOVÁNÍ VÝSTUPŮ (MASTER MATICE)\n\n**Cíl:** Vytvořit systémovou databázi pro křížové porovnání všech povinných komponent RVP se ŠVP.\n\n- **Dekompozice RVP:** Rozložit RVP na základní povinné komponenty: Klíčové kompetence, Vzdělávací oblasti a obory, Očekávané výstupy (OVU), Průřezová témata (PT).\n- **Přiřazovací mapa:** Vytvořit hlavní kontrolní matici (Master Matice) pro záznam vazeb.\n\n| Oblast RVP | Výstup RVP (OVU) | Odpovídající Část ŠVP (Předmět/Ročník) | Konkrétní Tématický Celek v ŠVP | Stav Shody (Protokol) |\n| --- | --- | --- | --- | --- |\n| ... | ... | ... | ... | ... |\n| --- | --- | --- | --- | --- |\n\n## FÁZE 3: ALGORITMICKÁ KONTROLA POKRYTÍ A HLOUBKY\n\n**Cíl:** Posoudit, zda každý povinný výstup RVP je adekvátně reflektován v obsahu ŠVP, a přidělit bodovou hodnotu pro kvantifikaci.\n\n- **Audit OVU:** Projít každý jednotlivý Očekávaný výstup (OVU) z RVP.\n- **Kódování stavu a bodování:** U každého OVU v matici označit stav pokrytí dle následujícího schématu:\n\n| Kód (Protokol) | Popis (Kvalitativní zjištění) | Bodová hodnota (Kvantifikace) |\n| --- | --- | --- |\n| ✅ | Plná shoda (Výstup pokryt v plném rozsahu, odpovídající úrovni RVP) | 1,0 |\n| --- | --- | --- |\n| ⚠️ | Částečná shoda (Formální pokrytí, omezený rozsah, chybná návaznost) | 0,5 |\n| --- | --- | --- |\n| ❌ | Absence (Výstup zcela chybí v obsahu ŠVP) | 0,0 |\n| --- | --- | --- |\n\n- **Defektologie ŠVP:** Identifikovat a zaznamenat deficity ŠVP: Chybějící výstupy (❌), Sémantické překryvy, Přetížení obsahu.\n- **Kvalitativní posun:** Ověřit, zda je formulace výstupů v ŠVP **aktivní, měřitelná a v souladu** s úrovní RVP.\n\n## FÁZE 4: STRUKTURÁLNÍ VERIFIKACE NÁVAZNOSTI (VERTIKÁLA/HORIZONTÁLA)\n\n**Cíl:** Zkontrolovat logickou posloupnost a provázanost učiva v rámci ŠVP.\n\n- **Vertikální Kontrola:** Ověřit posloupnost OVU a učiva uvnitř jednoho předmětu/oblasti (postup od jednodušších ke složitějším konceptům napříč ročníky).\n- **Horizontální Kontrola:** Zkontrolovat logické provázání napříč vzdělávacími oblastmi a předměty (např. fyzika ↔ matematika).\n- **PT Integrace:** Audit reálné integrace Průřezových témat (PT) do konkrétních částí obsahu, metod a projektů.\n\n## FÁZE 5: ANALÝZA ŠKOLNÍ PROFILACE A ROZŠÍŘENÍ RVP\n\n**Cíl:** Validovat, že profilace školy je **v souladu** s RVP a nejedná se o **rozpor**.\n\n- **Nekonfliktnost:** Porovnat definovaný Profil absolventa školy s Klíčovými kompetencemi RVP. Profil ŠVP musí RVP rozvíjet, nikoli mu odporovat.\n- **Modularita:** Zkontrolovat, zda volitelné předměty a rozšiřující moduly logicky navazují na vzdělávací oblasti RVP.\n- **Implementace specializace:** Popisně uvést, jak je školní profilace (např. STEM zaměření, projektová výuka) integrována do OVU a kompetencí definovaných RVP.\n\n## FÁZE 6: GENERÁTOR ZÁVĚREČNÉ ZPRÁVY A KVANTIFIKACE\n\n**Cíl:** Syntetizovat výsledky, kvantifikovat soulad a generovat závazné návrhy na korekce.\n\n### 6.1 Kvantifikace Souladu\n\nVypočítat Index shody (IS) na základě bodového hodnocení (Fáze 3):\n\n### 6.2 Interpretace Indexu Shody (IS)\n\nKlasifikace souladu pro standardizované vyhodnocení:\n\n| Interval IS | Klasifikace souladu | Popis |\n| --- | --- | --- |\n| 95-100 % | Výborný soulad | ŠVP plně odpovídá RVP, pouze stylistické nebo formální rozdíly. |\n| --- | --- | --- |\n| 85-94 % | Dobrá shoda | ŠVP pokrývá všechny klíčové výstupy, menší korekce nutné. |\n| --- | --- | --- |\n| 70-84 % | Částečná shoda | Významné nedostatky v některých oblastech, nutná revize obsahu. |\n| --- | --- | --- |\n| < 70 % | Kritická neshoda | ŠVP neplní rámcové požadavky, ohrožuje legislativní soulad. |\n| --- | --- | --- |\n\n### 6.3 Doplňkové Indexy\n\nVypočítat následující doplňkové indexy pro detailní kvalitativní analýzu:\n\n- **Index kompetenčního souladu (IKS):** Poměr pokrytí klíčových kompetencí RVP v ŠVP.\n- **Index průřezové integrace (IPI):** Míra reálné integrace průřezových témat do výuky.\n- **Index hloubky pokrytí (IHP):** Procento výstupů, které jsou v ŠVP rozvedeny na konkrétní výukové cíle (měřitelné, aktivní formulace).\n- **Index profilové rozšiřitelnosti (IPR):** Kolik rozšiřujících nebo profilových výstupů přesahuje rámec RVP, aniž by narušily jeho strukturu.\n\n### 6.4 Vizuální výstupy\n\nZajistit generování následujících vizualizací pro Závěrečnou zprávu:\n\n- Graf pokrytí po vzdělávacích oblastech (Sloupcový graf IS pro VO).\n- Pavoukový diagram Klíčových kompetencí (RVP vs. ŠVP).\n- Mapa defektů (Vizualizace ❌ a ⚠️ výstupů).\n\n### 6.5 Struktura Závěrečné Zprávy\n\nZpráva musí být strukturována dle standardizovaného formátu:\n\n| Oddíl | Obsah |\n| --- | --- |\n| A. Identifikace | Název školy, IZO, typ školy, datum revize, zpracovatel, verze ŠVP a RVP. |\n| --- | --- |\n| B. Shrnutí výsledků | Celkový Index Shody (IS), hlavní závěry a doporučení. |\n| --- | --- |\n| C. Kvantitativní analýza | Přehled IS v % dle kategorií OVU / VO / kompetencí. |\n| --- | --- |\n| D. Kvalitativní analýza | Slovní zhodnocení kvality souladu (formulace, obtížnost, integrace PT). |\n| --- | --- |\n| E. Rizikové oblasti | Přehled nalezených defektů (chybějící OVU, přetížení, formální shoda). |\n| --- | --- |\n| F. Návrhy opatření (Korekční plán) | Přesné návrhy změn - **Co, Kde, Kdo** má upravit, včetně termínu. |\n| --- | --- |\n| G. Přílohy | Master Matice (Fáze 2-3), revizní tabulka, výstupní grafy a metriky. |\n| --- | --- |\n\n\n\n\n.\n"}],sourceFile:"./books/examples/lsvp-asistent.book"}];
2071
+ var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book",formfactorName:"GENERIC",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",resultingParameterName:"knowledgePieces",dependentParameterNames:["knowledgeContent"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Knowledge from Markdown\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.book`\n- INPUT PARAMETER `{knowledgeContent}` Markdown document content\n- OUTPUT PARAMETER `{knowledgePieces}` The knowledge JSON object\n\n## Knowledge\n\n<!-- TODO: [🍆] -FORMAT JSON -->\n\n```markdown\nYou are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}\n```\n\n`-> {knowledgePieces}`\n"}],sourceFile:"./books/prepare-knowledge-from-markdown.book"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.book",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"knowledge",title:"Knowledge",content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",resultingParameterName:"keywords",dependentParameterNames:["knowledgePieceContent"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Keywords\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-keywords.book`\n- INPUT PARAMETER `{knowledgePieceContent}` The content\n- OUTPUT PARAMETER `{keywords}` Keywords separated by comma\n\n## Knowledge\n\n<!-- TODO: [🍆] -FORMAT JSON -->\n\n```markdown\nYou are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}\n```\n\n`-> {keywords}`\n"}],sourceFile:"./books/prepare-knowledge-keywords.book"},{title:"Prepare Knowledge-piece Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.book",formfactorName:"GENERIC",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"knowledge",title:"Knowledge",content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",resultingParameterName:"title",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Knowledge-piece Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-knowledge-title.book`\n- INPUT PARAMETER `{knowledgePieceContent}` The content\n- OUTPUT PARAMETER `{title}` The title of the document\n\n## Knowledge\n\n- EXPECT MIN 1 WORD\n- EXPECT MAX 8 WORDS\n\n```markdown\nYou are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-knowledge-title.book"},{title:"Prepare Persona",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.book",formfactorName:"GENERIC",parameters:[{name:"availableModels",description:"List of available model names together with their descriptions as JSON",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelsRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"make-model-requirements",title:"Make modelRequirements",content:"You are an experienced AI engineer, you need to find the best models for virtual assistants:\n\n## Example\n\n```json\n[\n {\n \"modelName\": \"gpt-4o\",\n \"systemMessage\": \"You are experienced AI engineer and helpful assistant.\",\n \"temperature\": 0.7\n },\n {\n \"modelName\": \"claude-3-5-sonnet\",\n \"systemMessage\": \"You are a friendly and knowledgeable chatbot.\",\n \"temperature\": 0.5\n }\n]\n```\n\n## Instructions\n\n- Your output format is JSON array\n- Sort best-fitting models first\n- Omit any models that are not suitable\n- Write just the JSON, no other text should be present\n- Array contain items with following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nHere are the available models:\n\n```json\n{availableModels}\n```\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",resultingParameterName:"modelsRequirements",format:"JSON",dependentParameterNames:["availableModels","personaDescription"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Persona\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-persona.book`\n- INPUT PARAMETER `{availableModels}` List of available model names together with their descriptions as JSON\n- INPUT PARAMETER `{personaDescription}` Description of the persona\n- OUTPUT PARAMETER `{modelsRequirements}` Specific requirements for the model\n\n## Make modelRequirements\n\n- FORMAT JSON\n\n```markdown\nYou are an experienced AI engineer, you need to find the best models for virtual assistants:\n\n## Example\n\n\\`\\`\\`json\n[\n {\n \"modelName\": \"gpt-4o\",\n \"systemMessage\": \"You are experienced AI engineer and helpful assistant.\",\n \"temperature\": 0.7\n },\n {\n \"modelName\": \"claude-3-5-sonnet\",\n \"systemMessage\": \"You are a friendly and knowledgeable chatbot.\",\n \"temperature\": 0.5\n }\n]\n\\`\\`\\`\n\n## Instructions\n\n- Your output format is JSON array\n- Sort best-fitting models first\n- Omit any models that are not suitable\n- Write just the JSON, no other text should be present\n- Array contain items with following keys:\n - `modelName`: The name of the model to use\n - `systemMessage`: The system message to provide context to the model\n - `temperature`: The sampling temperature to use\n\n### Key `modelName`\n\nHere are the available models:\n\n\\`\\`\\`json\n{availableModels}\n\\`\\`\\`\n\n### Key `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Key `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}\n```\n\n`-> {modelsRequirements}`\n"}],sourceFile:"./books/prepare-persona.book"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-title.book",formfactorName:"GENERIC",parameters:[{name:"book",description:"The book to prepare the title for",isInput:true,isOutput:false},{name:"title",description:"Best title for the book",isInput:false,isOutput:true}],tasks:[{taskType:"PROMPT_TASK",name:"make-title",title:"Make title",content:"Make best title for given text which describes the workflow:\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\n- Title starts with emoticon\n- Title should not mention the input and output of the workflow but the main purpose of the workflow\n _For example, not \"✍ Convert Knowledge-piece to title\" but \"✍ Title\"_\n\n## The workflow\n\n> {book}",resultingParameterName:"title",expectations:{words:{min:1,max:8},lines:{min:1,max:1}},dependentParameterNames:["book"]}],personas:[],preparations:[],knowledgeSources:[],knowledgePieces:[],sources:[{type:"BOOK",path:null,content:"# Prepare Title\n\n- PIPELINE URL `https://promptbook.studio/promptbook/prepare-title.book`\n- INPUT PARAMETER `{book}` The book to prepare the title for\n- OUTPUT PARAMETER `{title}` Best title for the book\n\n## Make title\n\n- EXPECT MIN 1 Word\n- EXPECT MAX 8 Words\n- EXPECT EXACTLY 1 Line\n\n```markdown\nMake best title for given text which describes the workflow:\n\n## Rules\n\n- Write just title, nothing else\n- Title should be concise and clear - Write maximum ideally 2 words, maximum 5 words\n- Title starts with emoticon\n- Title should not mention the input and output of the workflow but the main purpose of the workflow\n _For example, not \"✍ Convert Knowledge-piece to title\" but \"✍ Title\"_\n\n## The workflow\n\n> {book}\n```\n\n`-> {title}`\n"}],sourceFile:"./books/prepare-title.book"}];
2084
2072
 
2085
2073
  /**
2086
2074
  * Checks if value is valid email
@@ -2179,6 +2167,8 @@ function isValidJsonString(value /* <- [👨‍⚖️] */) {
2179
2167
  * Function `validatePipelineString` will validate the if the string is a valid pipeline string
2180
2168
  * It does not check if the string is fully logically correct, but if it is a string that can be a pipeline string or the string looks completely different.
2181
2169
  *
2170
+ * Note: [🔂] This function is idempotent.
2171
+ *
2182
2172
  * @param {string} pipelineString the candidate for a pipeline string
2183
2173
  * @returns {PipelineString} the same string as input, but validated as valid
2184
2174
  * @throws {ParseError} if the string is not a valid pipeline string
@@ -2338,7 +2328,7 @@ function pipelineJsonToString(pipelineJson) {
2338
2328
  pipelineString += '\n\n';
2339
2329
  pipelineString += '```' + contentLanguage;
2340
2330
  pipelineString += '\n';
2341
- pipelineString += spaceTrim(content);
2331
+ pipelineString += spaceTrim$2(content);
2342
2332
  // <- TODO: [main] !!3 Escape
2343
2333
  // <- TODO: [🧠] Some clear strategy how to spaceTrim the blocks
2344
2334
  pipelineString += '\n';
@@ -2452,7 +2442,7 @@ function unpreparePipeline(pipeline) {
2452
2442
  * Library of pipelines that groups together pipelines for an application.
2453
2443
  * This implementation is a very thin wrapper around the Array / Map of pipelines.
2454
2444
  *
2455
- * @private internal function of `createCollectionFromJson`, use `createCollectionFromJson` instead
2445
+ * @private internal function of `createPipelineCollectionFromJson`, use `createPipelineCollectionFromJson` instead
2456
2446
  * @see https://github.com/webgptorg/pipeline#pipeline-collection
2457
2447
  */
2458
2448
  class SimplePipelineCollection {
@@ -2462,7 +2452,7 @@ class SimplePipelineCollection {
2462
2452
  * @param pipelines Array of pipeline JSON objects to include in the collection
2463
2453
  *
2464
2454
  * Note: During the construction logic of all pipelines are validated
2465
- * Note: It is not recommended to use this constructor directly, use `createCollectionFromJson` *(or other variant)* instead
2455
+ * Note: It is not recommended to use this constructor directly, use `createPipelineCollectionFromJson` *(or other variant)* instead
2466
2456
  */
2467
2457
  constructor(...pipelines) {
2468
2458
  this.collection = new Map();
@@ -2550,16 +2540,16 @@ class SimplePipelineCollection {
2550
2540
  }
2551
2541
 
2552
2542
  /**
2553
- * Creates PipelineCollection from array of PipelineJson or PipelineString
2543
+ * Creates `PipelineCollection` from array of PipelineJson or PipelineString
2554
2544
  *
2555
- * Note: Functions `collectionToJson` and `createCollectionFromJson` are complementary
2545
+ * Note: Functions `pipelineCollectionToJson` and `createPipelineCollectionFromJson` are complementary
2556
2546
  * Note: Syntax, parsing, and logic consistency checks are performed on all sources during build
2557
2547
  *
2558
2548
  * @param promptbookSources
2559
2549
  * @returns PipelineCollection
2560
2550
  * @public exported from `@promptbook/core`
2561
2551
  */
2562
- function createCollectionFromJson(...promptbooks) {
2552
+ function createPipelineCollectionFromJson(...promptbooks) {
2563
2553
  return new SimplePipelineCollection(...promptbooks);
2564
2554
  }
2565
2555
 
@@ -2677,6 +2667,22 @@ class CollectionError extends Error {
2677
2667
  }
2678
2668
  }
2679
2669
 
2670
+ /**
2671
+ * This error indicates error from the database
2672
+ *
2673
+ * @public exported from `@promptbook/core`
2674
+ */
2675
+ class DatabaseError extends Error {
2676
+ constructor(message) {
2677
+ super(message);
2678
+ this.name = 'DatabaseError';
2679
+ Object.setPrototypeOf(this, DatabaseError.prototype);
2680
+ }
2681
+ }
2682
+ /**
2683
+ * TODO: [🐱‍🚀] Explain that NotFoundError ([🐱‍🚀] and other specific errors) has priority over DatabaseError in some contexts
2684
+ */
2685
+
2680
2686
  /**
2681
2687
  * This error type indicates that you try to use a feature that is not available in the current environment
2682
2688
  *
@@ -2732,6 +2738,19 @@ class LimitReachedError extends Error {
2732
2738
  }
2733
2739
  }
2734
2740
 
2741
+ /**
2742
+ * This error indicates that promptbook operation is not allowed
2743
+ *
2744
+ * @public exported from `@promptbook/core`
2745
+ */
2746
+ class NotAllowed extends Error {
2747
+ constructor(message) {
2748
+ super(message);
2749
+ this.name = 'NotAllowed';
2750
+ Object.setPrototypeOf(this, NotAllowed.prototype);
2751
+ }
2752
+ }
2753
+
2735
2754
  /**
2736
2755
  * This error type indicates that some part of the code is not implemented yet
2737
2756
  *
@@ -2758,6 +2777,7 @@ class NotYetImplementedError extends Error {
2758
2777
  /**
2759
2778
  * Generates random token
2760
2779
  *
2780
+ * Note: `$` is used to indicate that this function is not a pure function - it is not deterministic
2761
2781
  * Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
2762
2782
  *
2763
2783
  * @private internal helper function
@@ -2767,6 +2787,7 @@ function $randomToken(randomness) {
2767
2787
  return randomBytes(randomness).toString('hex');
2768
2788
  }
2769
2789
  /**
2790
+ * TODO: [🤶] Maybe export through `@promptbook/utils` or `@promptbook/random` package
2770
2791
  * TODO: Maybe use nanoid instead https://github.com/ai/nanoid
2771
2792
  */
2772
2793
 
@@ -2826,6 +2847,8 @@ const PROMPTBOOK_ERRORS = {
2826
2847
  PromptbookFetchError,
2827
2848
  UnexpectedError,
2828
2849
  WrappedError,
2850
+ NotAllowed,
2851
+ DatabaseError,
2829
2852
  // TODO: [🪑]> VersionMismatchError,
2830
2853
  };
2831
2854
  /**
@@ -2873,7 +2896,7 @@ function serializeError(error) {
2873
2896
  const { name, message, stack } = error;
2874
2897
  const { id } = error;
2875
2898
  if (!Object.keys(ALL_ERRORS).includes(name)) {
2876
- console.error(spaceTrim((block) => `
2899
+ console.error(spaceTrim$2((block) => `
2877
2900
 
2878
2901
  Cannot serialize error with name "${name}"
2879
2902
 
@@ -2937,7 +2960,7 @@ function deserializeError(error) {
2937
2960
  message = `${name}: ${message}`;
2938
2961
  }
2939
2962
  if (stack !== undefined && stack !== '') {
2940
- message = spaceTrim((block) => `
2963
+ message = spaceTrim$2((block) => `
2941
2964
  ${block(message)}
2942
2965
 
2943
2966
  Original stack trace:
@@ -3005,6 +3028,7 @@ function createTask(options) {
3005
3028
  let updatedAt = createdAt;
3006
3029
  const errors = [];
3007
3030
  const warnings = [];
3031
+ const llmCalls = [];
3008
3032
  let currentValue = {};
3009
3033
  let customTldr = null;
3010
3034
  const partialResultSubject = new Subject();
@@ -3020,6 +3044,9 @@ function createTask(options) {
3020
3044
  }, (tldrInfo) => {
3021
3045
  customTldr = tldrInfo;
3022
3046
  updatedAt = new Date();
3047
+ }, (llmCall) => {
3048
+ llmCalls.push(llmCall);
3049
+ updatedAt = new Date();
3023
3050
  });
3024
3051
  finalResultPromise
3025
3052
  .catch((error) => {
@@ -3142,7 +3169,7 @@ function createTask(options) {
3142
3169
  }
3143
3170
  return {
3144
3171
  percent: percent,
3145
- message,
3172
+ message: message + ' (!!!fallback)',
3146
3173
  };
3147
3174
  },
3148
3175
  get createdAt() {
@@ -3165,6 +3192,10 @@ function createTask(options) {
3165
3192
  return warnings;
3166
3193
  // <- Note: [1] --||--
3167
3194
  },
3195
+ get llmCalls() {
3196
+ return [...llmCalls, { foo: '!!! bar' }];
3197
+ // <- Note: [1] --||--
3198
+ },
3168
3199
  get currentValue() {
3169
3200
  return currentValue;
3170
3201
  // <- Note: [1] --||--
@@ -3607,7 +3638,7 @@ const CsvFormatParser = {
3607
3638
  const { value, outputParameterName, settings, mapCallback, onProgress } = options;
3608
3639
  const csv = csvParse(value, settings);
3609
3640
  if (csv.errors.length !== 0) {
3610
- throw new CsvFormatError(spaceTrim((block) => `
3641
+ throw new CsvFormatError(spaceTrim$2((block) => `
3611
3642
  CSV parsing error
3612
3643
 
3613
3644
  Error(s) from CSV parsing:
@@ -3652,7 +3683,7 @@ const CsvFormatParser = {
3652
3683
  const { value, settings, mapCallback, onProgress } = options;
3653
3684
  const csv = csvParse(value, settings);
3654
3685
  if (csv.errors.length !== 0) {
3655
- throw new CsvFormatError(spaceTrim((block) => `
3686
+ throw new CsvFormatError(spaceTrim$2((block) => `
3656
3687
  CSV parsing error
3657
3688
 
3658
3689
  Error(s) from CSV parsing:
@@ -3862,7 +3893,7 @@ function mapAvailableToExpectedParameters(options) {
3862
3893
  }
3863
3894
  // Phase 2️⃣: Non-matching mapping
3864
3895
  if (expectedParameterNames.size !== availableParametersNames.size) {
3865
- throw new PipelineExecutionError(spaceTrim((block) => `
3896
+ throw new PipelineExecutionError(spaceTrim$2((block) => `
3866
3897
  Can not map available parameters to expected parameters
3867
3898
 
3868
3899
  Mapped parameters:
@@ -3940,14 +3971,14 @@ class MultipleLlmExecutionTools {
3940
3971
  if (description === undefined) {
3941
3972
  return headLine;
3942
3973
  }
3943
- return spaceTrim((block) => `
3974
+ return spaceTrim$2((block) => `
3944
3975
  ${headLine}
3945
3976
 
3946
3977
  ${ /* <- Note: Indenting the description: */block(description)}
3947
3978
  `);
3948
3979
  })
3949
3980
  .join('\n\n');
3950
- return spaceTrim((block) => `
3981
+ return spaceTrim$2((block) => `
3951
3982
  Multiple LLM Providers:
3952
3983
 
3953
3984
  ${block(innerModelsTitlesAndDescriptions)}
@@ -4038,7 +4069,7 @@ class MultipleLlmExecutionTools {
4038
4069
  // 1) OpenAI throw PipelineExecutionError: Parameter `{knowledge}` is not defined
4039
4070
  // 2) AnthropicClaude throw PipelineExecutionError: Parameter `{knowledge}` is not defined
4040
4071
  // 3) ...
4041
- spaceTrim((block) => `
4072
+ spaceTrim$2((block) => `
4042
4073
  All execution tools of ${this.title} failed:
4043
4074
 
4044
4075
  ${block(errors
@@ -4051,7 +4082,7 @@ class MultipleLlmExecutionTools {
4051
4082
  throw new PipelineExecutionError(`You have not provided any \`LlmExecutionTools\` into ${this.title}`);
4052
4083
  }
4053
4084
  else {
4054
- throw new PipelineExecutionError(spaceTrim((block) => `
4085
+ throw new PipelineExecutionError(spaceTrim$2((block) => `
4055
4086
  You have not provided any \`LlmExecutionTools\` that support model variant "${prompt.modelRequirements.modelVariant}" into ${this.title}
4056
4087
 
4057
4088
  Available \`LlmExecutionTools\`:
@@ -4084,7 +4115,7 @@ class MultipleLlmExecutionTools {
4084
4115
  */
4085
4116
  function joinLlmExecutionTools(title, ...llmExecutionTools) {
4086
4117
  if (llmExecutionTools.length === 0) {
4087
- const warningMessage = spaceTrim(`
4118
+ const warningMessage = spaceTrim$2(`
4088
4119
  You have not provided any \`LlmExecutionTools\`
4089
4120
  This means that you won't be able to execute any prompts that require large language models like GPT-4 or Anthropic's Claude.
4090
4121
 
@@ -4117,6 +4148,7 @@ function joinLlmExecutionTools(title, ...llmExecutionTools) {
4117
4148
  return new MultipleLlmExecutionTools(title || 'Multiple LLM Providers joined by `joinLlmExecutionTools`', ...llmExecutionTools);
4118
4149
  }
4119
4150
  /**
4151
+ * TODO: [🙆] `getSingleLlmExecutionTools` vs `joinLlmExecutionTools` - explain difference or pick one
4120
4152
  * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
4121
4153
  */
4122
4154
 
@@ -4133,6 +4165,7 @@ function getSingleLlmExecutionTools(oneOrMoreLlmExecutionTools) {
4133
4165
  return llmTools;
4134
4166
  }
4135
4167
  /**
4168
+ * TODO: [🙆] `getSingleLlmExecutionTools` vs `joinLlmExecutionTools` - explain difference or pick one
4136
4169
  * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
4137
4170
  */
4138
4171
 
@@ -4370,10 +4403,13 @@ const LINES_PER_STANDARD_PAGE = 44;
4370
4403
  * @public exported from `@promptbook/utils`
4371
4404
  */
4372
4405
  function countLines(text) {
4406
+ if (text === '') {
4407
+ return 0;
4408
+ }
4373
4409
  text = text.replace('\r\n', '\n');
4374
4410
  text = text.replace('\r', '\n');
4375
4411
  const lines = text.split('\n');
4376
- return lines.reduce((count, line) => count + Math.ceil(line.length / CHARACTERS_PER_STANDARD_LINE), 0);
4412
+ return lines.reduce((count, line) => count + Math.max(Math.ceil(line.length / CHARACTERS_PER_STANDARD_LINE), 1), 0);
4377
4413
  }
4378
4414
  /**
4379
4415
  * TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
@@ -4761,6 +4797,8 @@ function checkExpectations(expectations, value) {
4761
4797
  * This function provides a common abstraction for result validation that can be used
4762
4798
  * by both execution logic and caching logic to ensure consistency.
4763
4799
  *
4800
+ * Note: [🔂] This function is idempotent.
4801
+ *
4764
4802
  * @param options - The validation options including result string, expectations, and format
4765
4803
  * @returns Validation result with processed string and validity status
4766
4804
  * @private internal function of `createPipelineExecutor` and `cacheLlmTools`
@@ -4829,7 +4867,7 @@ function validatePromptResult(options) {
4829
4867
  */
4830
4868
  async function executeAttempts(options) {
4831
4869
  const { jokerParameterNames, priority, maxAttempts, // <- Note: [💂]
4832
- preparedContent, parameters, task, preparedPipeline, tools, $executionReport, pipelineIdentification, maxExecutionAttempts, onProgress, } = options;
4870
+ preparedContent, parameters, task, preparedPipeline, tools, $executionReport, pipelineIdentification, maxExecutionAttempts, onProgress, logLlmCall, } = options;
4833
4871
  const $ongoingTaskResult = {
4834
4872
  $result: null,
4835
4873
  $resultString: null,
@@ -5077,14 +5115,10 @@ async function executeAttempts(options) {
5077
5115
  });
5078
5116
  }
5079
5117
  finally {
5080
- if (!isJokerAttempt &&
5081
- task.taskType === 'PROMPT_TASK' &&
5082
- $ongoingTaskResult.$prompt
5083
- // <- Note: [2] When some expected parameter is not defined, error will occur in templateParameters
5084
- // In that case we don’t want to make a report about it because it’s not a llm execution error
5085
- ) {
5086
- // TODO: [🧠] Maybe put other taskTypes into report
5087
- $executionReport.promptExecutions.push({
5118
+ if (!isJokerAttempt && task.taskType === 'PROMPT_TASK' && $ongoingTaskResult.$prompt) {
5119
+ // Note: [2] When some expected parameter is not defined, error will occur in templateParameters
5120
+ // In that case we don’t want to make a report about it because it’s not a llm execution error
5121
+ const executionPromptReport = {
5088
5122
  prompt: {
5089
5123
  ...$ongoingTaskResult.$prompt,
5090
5124
  // <- TODO: [🧠] How to pick everyhing except `pipelineUrl`
@@ -5093,7 +5127,14 @@ async function executeAttempts(options) {
5093
5127
  error: $ongoingTaskResult.$expectError === null
5094
5128
  ? undefined
5095
5129
  : serializeError($ongoingTaskResult.$expectError),
5096
- });
5130
+ };
5131
+ $executionReport.promptExecutions.push(executionPromptReport);
5132
+ if (logLlmCall) {
5133
+ logLlmCall({
5134
+ modelName: 'model' /* <- TODO: How to get model name from the report */,
5135
+ report: executionPromptReport,
5136
+ });
5137
+ }
5097
5138
  }
5098
5139
  }
5099
5140
  if ($ongoingTaskResult.$expectError !== null && attemptIndex === maxAttempts - 1) {
@@ -5158,12 +5199,12 @@ async function executeAttempts(options) {
5158
5199
  * @private internal utility of `createPipelineExecutor`
5159
5200
  */
5160
5201
  async function executeFormatSubvalues(options) {
5161
- const { task, jokerParameterNames, parameters, priority, csvSettings, onProgress, pipelineIdentification } = options;
5202
+ const { task, jokerParameterNames, parameters, priority, csvSettings, onProgress, logLlmCall, pipelineIdentification, } = options;
5162
5203
  if (task.foreach === undefined) {
5163
- return /* not await */ executeAttempts(options);
5204
+ return /* not await */ executeAttempts({ ...options, logLlmCall });
5164
5205
  }
5165
5206
  if (jokerParameterNames.length !== 0) {
5166
- throw new UnexpectedError(spaceTrim((block) => `
5207
+ throw new UnexpectedError(spaceTrim$2((block) => `
5167
5208
  JOKER parameters are not supported together with FOREACH command
5168
5209
 
5169
5210
  [🧞‍♀️] This should be prevented in \`validatePipeline\`
@@ -5176,7 +5217,7 @@ async function executeFormatSubvalues(options) {
5176
5217
  if (formatDefinition === undefined) {
5177
5218
  throw new UnexpectedError(
5178
5219
  // <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
5179
- spaceTrim((block) => `
5220
+ spaceTrim$2((block) => `
5180
5221
  Unsupported format "${task.foreach.formatName}"
5181
5222
 
5182
5223
  Available formats:
@@ -5193,7 +5234,7 @@ async function executeFormatSubvalues(options) {
5193
5234
  if (subvalueParser === undefined) {
5194
5235
  throw new UnexpectedError(
5195
5236
  // <- TODO: [🧠][🧐] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
5196
- spaceTrim((block) => `
5237
+ spaceTrim$2((block) => `
5197
5238
  Unsupported subformat name "${task.foreach.subformatName}" for format "${task.foreach.formatName}"
5198
5239
 
5199
5240
  Available subformat names for format "${formatDefinition.formatName}":
@@ -5233,7 +5274,7 @@ async function executeFormatSubvalues(options) {
5233
5274
  if (!(error instanceof PipelineExecutionError)) {
5234
5275
  throw error;
5235
5276
  }
5236
- const highLevelError = new PipelineExecutionError(spaceTrim((block) => `
5277
+ const highLevelError = new PipelineExecutionError(spaceTrim$2((block) => `
5237
5278
  ${error.message}
5238
5279
 
5239
5280
  This is error in FOREACH command when mapping ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
@@ -5257,7 +5298,7 @@ async function executeFormatSubvalues(options) {
5257
5298
  ...options,
5258
5299
  priority: priority + index,
5259
5300
  parameters: allSubparameters,
5260
- pipelineIdentification: spaceTrim((block) => `
5301
+ pipelineIdentification: spaceTrim$2((block) => `
5261
5302
  ${block(pipelineIdentification)}
5262
5303
  Subparameter index: ${index}
5263
5304
  `),
@@ -5266,7 +5307,7 @@ async function executeFormatSubvalues(options) {
5266
5307
  }
5267
5308
  catch (error) {
5268
5309
  if (length > BIG_DATASET_TRESHOLD) {
5269
- console.error(spaceTrim((block) => `
5310
+ console.error(spaceTrim$2((block) => `
5270
5311
  ${error.message}
5271
5312
 
5272
5313
  This is error in FOREACH command when processing ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
@@ -5366,7 +5407,7 @@ async function getKnowledgeForTask(options) {
5366
5407
  },
5367
5408
  content: task.content,
5368
5409
  parameters,
5369
- };
5410
+ }; /* <- Note: [🤛] */
5370
5411
  const taskEmbeddingResult = await llmTools.callEmbeddingModel(taskEmbeddingPrompt);
5371
5412
  const knowledgePiecesWithRelevance = preparedPipeline.knowledgePieces.map((knowledgePiece) => {
5372
5413
  const { index } = knowledgePiece;
@@ -5461,7 +5502,7 @@ async function getReservedParametersForTask(options) {
5461
5502
  * @private internal utility of `createPipelineExecutor`
5462
5503
  */
5463
5504
  async function executeTask(options) {
5464
- const { currentTask, preparedPipeline, parametersToPass, tools, onProgress, $executionReport, pipelineIdentification, maxExecutionAttempts, maxParallelCount, csvSettings, isVerbose, rootDirname, cacheDirname, intermediateFilesStrategy, isAutoInstalled, isNotPreparedWarningSuppressed, } = options;
5505
+ const { currentTask, preparedPipeline, parametersToPass, tools, onProgress, logLlmCall, $executionReport, pipelineIdentification, maxExecutionAttempts, maxParallelCount, csvSettings, isVerbose, rootDirname, cacheDirname, intermediateFilesStrategy, isAutoInstalled, isNotPreparedWarningSuppressed, } = options;
5465
5506
  const priority = preparedPipeline.tasks.length - preparedPipeline.tasks.indexOf(currentTask);
5466
5507
  // Note: Check consistency of used and dependent parameters which was also done in `validatePipeline`, but it’s good to doublecheck
5467
5508
  const usedParameterNames = extractParameterNamesFromTask(currentTask);
@@ -5540,6 +5581,7 @@ async function executeTask(options) {
5540
5581
  tools,
5541
5582
  $executionReport,
5542
5583
  onProgress,
5584
+ logLlmCall,
5543
5585
  pipelineIdentification,
5544
5586
  maxExecutionAttempts,
5545
5587
  maxParallelCount,
@@ -5583,6 +5625,29 @@ function filterJustOutputParameters(options) {
5583
5625
  $warnings.push(new PipelineExecutionError(spaceTrim$1((block) => `
5584
5626
  Parameter \`{${parameter.name}}\` should be an output parameter, but it was not generated during pipeline execution
5585
5627
 
5628
+ Note: This is a warning which happened after the pipeline was executed, and \`{${parameter.name}}\` was not for some reason defined in output parameters
5629
+
5630
+ All parameters:
5631
+ ${block(preparedPipeline.parameters
5632
+ .map(({ name, isInput, isOutput, description }) => {
5633
+ let line = `\`{${name}}\``;
5634
+ if (isInput) {
5635
+ line += ' `[input parameter]`';
5636
+ }
5637
+ if (isOutput) {
5638
+ line += ' `[output parameter]`';
5639
+ }
5640
+ if (parametersToPass[name] === undefined) {
5641
+ line += ` <- Warning: Should be in the output but its not |`;
5642
+ }
5643
+ if (description) {
5644
+ line += ` ${description}`;
5645
+ }
5646
+ return line;
5647
+ })
5648
+ .map((line, index) => `${index + 1}) ${line}`)
5649
+ .join('\n'))}
5650
+
5586
5651
  ${block(pipelineIdentification)}
5587
5652
  `)));
5588
5653
  continue;
@@ -5603,7 +5668,7 @@ function filterJustOutputParameters(options) {
5603
5668
  * @private internal utility of `createPipelineExecutor`
5604
5669
  */
5605
5670
  async function executePipeline(options) {
5606
- const { inputParameters, tools, onProgress, pipeline, setPreparedPipeline, pipelineIdentification, maxParallelCount, rootDirname, isVerbose, } = options;
5671
+ const { inputParameters, tools, onProgress, logLlmCall, pipeline, setPreparedPipeline, pipelineIdentification, maxParallelCount, rootDirname, isVerbose, } = options;
5607
5672
  let { preparedPipeline } = options;
5608
5673
  if (preparedPipeline === undefined) {
5609
5674
  preparedPipeline = await preparePipeline(pipeline, tools, {
@@ -5781,6 +5846,7 @@ async function executePipeline(options) {
5781
5846
  onProgress(newOngoingResult);
5782
5847
  }
5783
5848
  },
5849
+ logLlmCall,
5784
5850
  $executionReport: executionReport,
5785
5851
  pipelineIdentification: spaceTrim$1((block) => `
5786
5852
  ${block(pipelineIdentification)}
@@ -5904,7 +5970,7 @@ function createPipelineExecutor(options) {
5904
5970
  // <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
5905
5971
  }
5906
5972
  let runCount = 0;
5907
- const pipelineExecutorWithCallback = async (inputParameters, onProgress) => {
5973
+ const pipelineExecutorWithCallback = async (inputParameters, onProgress, logLlmCall) => {
5908
5974
  runCount++;
5909
5975
  return /* not await */ executePipeline({
5910
5976
  pipeline,
@@ -5915,6 +5981,7 @@ function createPipelineExecutor(options) {
5915
5981
  inputParameters,
5916
5982
  tools,
5917
5983
  onProgress,
5984
+ logLlmCall,
5918
5985
  pipelineIdentification: spaceTrim$1((block) => `
5919
5986
  ${block(pipelineIdentification)}
5920
5987
  ${runCount === 1 ? '' : `Run #${runCount}`}
@@ -6132,7 +6199,7 @@ async function preparePersona(personaDescription, tools, options) {
6132
6199
  throw new MissingToolsError('LLM tools are required for preparing persona');
6133
6200
  }
6134
6201
  // TODO: [🌼] In future use `ptbk make` and made getPipelineCollection
6135
- const collection = createCollectionFromJson(...PipelineCollection);
6202
+ const collection = createPipelineCollectionFromJson(...PipelineCollection);
6136
6203
  const preparePersonaExecutor = createPipelineExecutor({
6137
6204
  pipeline: await collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-persona.book'),
6138
6205
  tools,
@@ -6383,14 +6450,14 @@ function $registeredScrapersMessage(availableScrapers) {
6383
6450
  return { ...metadata, isMetadataAviailable, isInstalled, isAvailableInTools };
6384
6451
  });
6385
6452
  if (metadata.length === 0) {
6386
- return spaceTrim(`
6453
+ return spaceTrim$2(`
6387
6454
  **No scrapers are available**
6388
6455
 
6389
6456
  This is a unexpected behavior, you are probably using some broken version of Promptbook
6390
6457
  At least there should be available the metadata of the scrapers
6391
6458
  `);
6392
6459
  }
6393
- return spaceTrim((block) => `
6460
+ return spaceTrim$2((block) => `
6394
6461
  Available scrapers are:
6395
6462
  ${block(metadata
6396
6463
  .map(({ packageName, className, isMetadataAviailable, isInstalled, mimeTypes, isAvailableInBrowser, isAvailableInTools, }, i) => {
@@ -6435,6 +6502,8 @@ function $registeredScrapersMessage(availableScrapers) {
6435
6502
  /**
6436
6503
  * Converts a given text to kebab-case format.
6437
6504
  *
6505
+ * Note: [🔂] This function is idempotent.
6506
+ *
6438
6507
  * @param text The text to be converted.
6439
6508
  * @returns The kebab-case formatted string.
6440
6509
  * @example 'hello-world'
@@ -6590,6 +6659,8 @@ function removeEmojis(text) {
6590
6659
  /**
6591
6660
  * Converts a title string into a normalized name.
6592
6661
  *
6662
+ * Note: [🔂] This function is idempotent.
6663
+ *
6593
6664
  * @param value The title string to be converted to a name.
6594
6665
  * @returns A normalized name derived from the input title.
6595
6666
  * @example 'Hello World!' -> 'hello-world'
@@ -6629,7 +6700,7 @@ const promptbookFetch = async (urlOrRequest, init) => {
6629
6700
  else if (urlOrRequest instanceof Request) {
6630
6701
  url = urlOrRequest.url;
6631
6702
  }
6632
- throw new PromptbookFetchError(spaceTrim((block) => `
6703
+ throw new PromptbookFetchError(spaceTrim$2((block) => `
6633
6704
  Can not fetch "${url}"
6634
6705
 
6635
6706
  Fetch error:
@@ -6790,7 +6861,7 @@ async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
6790
6861
  const fileExtension = getFileExtension(filename);
6791
6862
  const mimeType = extensionToMimeType(fileExtension || '');
6792
6863
  if (!(await isFileExisting(filename, tools.fs))) {
6793
- throw new NotFoundError(spaceTrim((block) => `
6864
+ throw new NotFoundError(spaceTrim$2((block) => `
6794
6865
  Can not make source handler for file which does not exist:
6795
6866
 
6796
6867
  File:
@@ -6883,7 +6954,7 @@ async function prepareKnowledgePieces(knowledgeSources, tools, options) {
6883
6954
  // <- TODO: [🪓] Here should be no need for spreading new array, just `partialPieces = partialPiecesUnchecked`
6884
6955
  break;
6885
6956
  }
6886
- console.warn(spaceTrim((block) => `
6957
+ console.warn(spaceTrim$2((block) => `
6887
6958
  Cannot scrape knowledge from source despite the scraper \`${scraper.metadata.className}\` supports the mime type "${sourceHandler.mimeType}".
6888
6959
 
6889
6960
  The source:
@@ -6899,7 +6970,7 @@ async function prepareKnowledgePieces(knowledgeSources, tools, options) {
6899
6970
  // <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
6900
6971
  }
6901
6972
  if (partialPieces === null) {
6902
- throw new KnowledgeScrapeError(spaceTrim((block) => `
6973
+ throw new KnowledgeScrapeError(spaceTrim$2((block) => `
6903
6974
  Cannot scrape knowledge
6904
6975
 
6905
6976
  The source:
@@ -7064,7 +7135,7 @@ async function preparePipeline(pipeline, tools, options) {
7064
7135
  let title = pipeline.title;
7065
7136
  if (title === undefined || title === '' || title === DEFAULT_BOOK_TITLE) {
7066
7137
  // TODO: [🌼] In future use `ptbk make` and made getPipelineCollection
7067
- const collection = createCollectionFromJson(...PipelineCollection);
7138
+ const collection = createPipelineCollectionFromJson(...PipelineCollection);
7068
7139
  const prepareTitleExecutor = createPipelineExecutor({
7069
7140
  pipeline: await collection.getPipelineByUrl('https://promptbook.studio/promptbook/prepare-title.book'),
7070
7141
  tools,
@@ -7235,7 +7306,7 @@ const knowledgeCommandParser = {
7235
7306
  */
7236
7307
  parse(input) {
7237
7308
  const { args } = input;
7238
- const knowledgeSourceContent = spaceTrim(args[0] || '');
7309
+ const knowledgeSourceContent = spaceTrim$2(args[0] || '');
7239
7310
  if (knowledgeSourceContent === '') {
7240
7311
  throw new ParseError(`Source is not defined`);
7241
7312
  }
@@ -7379,7 +7450,7 @@ const sectionCommandParser = {
7379
7450
  normalized = normalized.split('DIALOGUE').join('DIALOG');
7380
7451
  const taskTypes = SectionTypes.filter((sectionType) => normalized.includes(sectionType.split('_TASK').join('')));
7381
7452
  if (taskTypes.length !== 1) {
7382
- throw new ParseError(spaceTrim((block) => `
7453
+ throw new ParseError(spaceTrim$2((block) => `
7383
7454
  Unknown section type "${normalized}"
7384
7455
 
7385
7456
  Supported section types are:
@@ -7399,7 +7470,7 @@ const sectionCommandParser = {
7399
7470
  */
7400
7471
  $applyToTaskJson(command, $taskJson, $pipelineJson) {
7401
7472
  if ($taskJson.isSectionTypeSet === true) {
7402
- throw new ParseError(spaceTrim(`
7473
+ throw new ParseError(spaceTrim$2(`
7403
7474
  Section type is already defined in the section.
7404
7475
  It can be defined only once.
7405
7476
  `));
@@ -7748,7 +7819,7 @@ const expectCommandParser = {
7748
7819
  /**
7749
7820
  * Description of the FORMAT command
7750
7821
  */
7751
- description: spaceTrim(`
7822
+ description: spaceTrim$2(`
7752
7823
  Expect command describes the desired output of the task *(after post-processing)*
7753
7824
  It can set limits for the maximum/minimum length of the output, measured in characters, words, sentences, paragraphs or some other shape of the output.
7754
7825
  `),
@@ -7822,7 +7893,7 @@ const expectCommandParser = {
7822
7893
  }
7823
7894
  catch (error) {
7824
7895
  assertsError(error);
7825
- throw new ParseError(spaceTrim((block) => `
7896
+ throw new ParseError(spaceTrim$2((block) => `
7826
7897
  Invalid FORMAT command
7827
7898
  ${block(error.message)}:
7828
7899
  `));
@@ -7872,6 +7943,8 @@ const expectCommandParser = {
7872
7943
  /**
7873
7944
  * Normalizes a given text to camelCase format.
7874
7945
  *
7946
+ * Note: [🔂] This function is idempotent.
7947
+ *
7875
7948
  * @param text The text to be normalized.
7876
7949
  * @param _isFirstLetterCapital Whether the first letter should be capitalized.
7877
7950
  * @returns The camelCase formatted string.
@@ -7949,6 +8022,8 @@ function removeQuotes(text) {
7949
8022
  * Function `validateParameterName` will normalize and validate a parameter name for use in pipelines.
7950
8023
  * It removes diacritics, emojis, and quotes, normalizes to camelCase, and checks for reserved names and invalid characters.
7951
8024
  *
8025
+ * Note: [🔂] This function is idempotent.
8026
+ *
7952
8027
  * @param parameterName The parameter name to validate and normalize.
7953
8028
  * @returns The validated and normalized parameter name.
7954
8029
  * @throws {ParseError} If the parameter name is empty, reserved, or contains invalid characters.
@@ -8008,7 +8083,7 @@ function validateParameterName(parameterName) {
8008
8083
  if (!(error instanceof ParseError)) {
8009
8084
  throw error;
8010
8085
  }
8011
- throw new ParseError(spaceTrim((block) => `
8086
+ throw new ParseError(spaceTrim$2((block) => `
8012
8087
  ${block(error.message)}
8013
8088
 
8014
8089
  Tried to validate parameter name:
@@ -8067,7 +8142,7 @@ const foreachCommandParser = {
8067
8142
  const assignSign = args[3];
8068
8143
  const formatDefinition = FORMAT_DEFINITIONS.find((formatDefinition) => [formatDefinition.formatName, ...(formatDefinition.aliases || [])].includes(formatName));
8069
8144
  if (formatDefinition === undefined) {
8070
- throw new ParseError(spaceTrim((block) => `
8145
+ throw new ParseError(spaceTrim$2((block) => `
8071
8146
  Unsupported format "${formatName}"
8072
8147
 
8073
8148
  Available formats:
@@ -8079,7 +8154,7 @@ const foreachCommandParser = {
8079
8154
  }
8080
8155
  const subvalueParser = formatDefinition.subvalueParsers.find((subvalueParser) => [subvalueParser.subvalueName, ...(subvalueParser.aliases || [])].includes(subformatName));
8081
8156
  if (subvalueParser === undefined) {
8082
- throw new ParseError(spaceTrim((block) => `
8157
+ throw new ParseError(spaceTrim$2((block) => `
8083
8158
  Unsupported subformat name "${subformatName}" for format "${formatName}"
8084
8159
 
8085
8160
  Available subformat names for format "${formatDefinition.formatName}":
@@ -8127,7 +8202,7 @@ const foreachCommandParser = {
8127
8202
  outputSubparameterName = 'newLine';
8128
8203
  }
8129
8204
  else {
8130
- throw new ParseError(spaceTrim(`
8205
+ throw new ParseError(spaceTrim$2(`
8131
8206
  FOREACH ${formatName} ${subformatName} must specify output subparameter
8132
8207
 
8133
8208
  Correct example:
@@ -8203,7 +8278,7 @@ const formatCommandParser = {
8203
8278
  /**
8204
8279
  * Description of the FORMAT command
8205
8280
  */
8206
- description: spaceTrim(`
8281
+ description: spaceTrim$2(`
8207
8282
  Format command describes the desired output of the task (after post-processing)
8208
8283
  It can set limits for the maximum/minimum length of the output, measured in characters, words, sentences, paragraphs or some other shape of the output.
8209
8284
  `),
@@ -8575,7 +8650,7 @@ const formfactorCommandParser = {
8575
8650
  const formfactorNameCandidate = args[0].toUpperCase();
8576
8651
  const formfactor = FORMFACTOR_DEFINITIONS.find((definition) => [definition.name, ...{ aliasNames: [], ...definition }.aliasNames].includes(formfactorNameCandidate));
8577
8652
  if (formfactor === undefined) {
8578
- throw new ParseError(spaceTrim((block) => `
8653
+ throw new ParseError(spaceTrim$2((block) => `
8579
8654
  Unknown formfactor name "${formfactorNameCandidate}"
8580
8655
 
8581
8656
  Available formfactors:
@@ -8594,7 +8669,7 @@ const formfactorCommandParser = {
8594
8669
  */
8595
8670
  $applyToPipelineJson(command, $pipelineJson) {
8596
8671
  if ($pipelineJson.formfactorName !== undefined && $pipelineJson.formfactorName !== command.formfactorName) {
8597
- throw new ParseError(spaceTrim(`
8672
+ throw new ParseError(spaceTrim$2(`
8598
8673
  Redefinition of \`FORMFACTOR\` in the pipeline head
8599
8674
 
8600
8675
  You have used:
@@ -8737,7 +8812,7 @@ const modelCommandParser = {
8737
8812
  */
8738
8813
  parse(input) {
8739
8814
  const { args, normalized } = input;
8740
- const availableVariantsMessage = spaceTrim((block) => `
8815
+ const availableVariantsMessage = spaceTrim$2((block) => `
8741
8816
  Available variants are:
8742
8817
  ${block(MODEL_VARIANTS.map((variantName) => `- ${variantName}${variantName !== 'EMBEDDING' ? '' : ' (Not available in pipeline)'}`).join('\n'))}
8743
8818
  `);
@@ -8759,14 +8834,14 @@ const modelCommandParser = {
8759
8834
  // <- Note: [🤖]
8760
8835
  }
8761
8836
  else if (normalized.startsWith('MODEL_VARIANT_EMBED')) {
8762
- spaceTrim((block) => `
8837
+ spaceTrim$2((block) => `
8763
8838
  Embedding model can not be used in pipeline
8764
8839
 
8765
8840
  ${block(availableVariantsMessage)}
8766
8841
  `);
8767
8842
  }
8768
8843
  else {
8769
- throw new ParseError(spaceTrim((block) => `
8844
+ throw new ParseError(spaceTrim$2((block) => `
8770
8845
  Unknown model variant in command:
8771
8846
 
8772
8847
  ${block(availableVariantsMessage)}
@@ -8781,7 +8856,7 @@ const modelCommandParser = {
8781
8856
  };
8782
8857
  }
8783
8858
  else {
8784
- throw new ParseError(spaceTrim((block) => `
8859
+ throw new ParseError(spaceTrim$2((block) => `
8785
8860
  Unknown model key in command.
8786
8861
 
8787
8862
  Supported model keys are:
@@ -8808,7 +8883,7 @@ const modelCommandParser = {
8808
8883
  // <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
8809
8884
  }
8810
8885
  else {
8811
- throw new ParseError(spaceTrim(`
8886
+ throw new ParseError(spaceTrim$2(`
8812
8887
  Redefinition of \`MODEL ${command.key}\` in the pipeline head
8813
8888
 
8814
8889
  You have used:
@@ -8840,7 +8915,7 @@ const modelCommandParser = {
8840
8915
  // <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
8841
8916
  }
8842
8917
  else {
8843
- throw new ParseError(spaceTrim(`
8918
+ throw new ParseError(spaceTrim$2(`
8844
8919
  Redefinition of MODEL \`${command.key}\` in the task "${$taskJson.title || $taskJson.name}"
8845
8920
 
8846
8921
  You have used:
@@ -8850,7 +8925,7 @@ const modelCommandParser = {
8850
8925
  }
8851
8926
  }
8852
8927
  if (command.value === ($pipelineJson.defaultModelRequirements || {})[command.key]) {
8853
- console.log(spaceTrim(`
8928
+ console.log(spaceTrim$2(`
8854
8929
  Setting MODEL \`${command.key}\` in the task "${$taskJson.title || $taskJson.name}" to the same value as in the pipeline head
8855
8930
 
8856
8931
  In pipeline head:
@@ -8933,7 +9008,7 @@ const parameterCommandParser = {
8933
9008
  // <- TODO: When [🥶] fixed, change to:
8934
9009
  // > const parameterDescriptionRaw = rawArgs.split(parameterNameRaw).join('').trim();
8935
9010
  if (parameterDescriptionRaw && parameterDescriptionRaw.match(/\{(?<embeddedParameterName>[a-z0-9_]+)\}/im)) {
8936
- throw new ParseError(spaceTrim((block) => `
9011
+ throw new ParseError(spaceTrim$2((block) => `
8937
9012
  Parameter \`{${parameterNameRaw}}\` can not contain another parameter in description
8938
9013
 
8939
9014
  The description:
@@ -9115,7 +9190,7 @@ function $applyToTaskJson(command, $taskJson, $pipelineJson) {
9115
9190
  persona.description = personaDescription;
9116
9191
  return;
9117
9192
  }
9118
- console.warn(spaceTrim(`
9193
+ console.warn(spaceTrim$2(`
9119
9194
 
9120
9195
  Persona "${personaName}" is defined multiple times with different description:
9121
9196
 
@@ -9126,7 +9201,7 @@ function $applyToTaskJson(command, $taskJson, $pipelineJson) {
9126
9201
  ${personaDescription}
9127
9202
 
9128
9203
  `));
9129
- persona.description += spaceTrim('\n\n' + personaDescription);
9204
+ persona.description += spaceTrim$2('\n\n' + personaDescription);
9130
9205
  }
9131
9206
 
9132
9207
  /**
@@ -9920,6 +9995,48 @@ const HIGH_LEVEL_ABSTRACTIONS = [
9920
9995
  const SUPPORTED_SCRIPT_LANGUAGES = ['javascript', 'typescript', 'python'];
9921
9996
  // <- TODO: [🏥] DRY
9922
9997
 
9998
+ /**
9999
+ * Number of padding lines to add at the end of the book content
10000
+ *
10001
+ * @public exported from `@promptbook/core`
10002
+ */
10003
+ const PADDING_LINES = 11;
10004
+ /**
10005
+ * A function that adds padding to the book content
10006
+ *
10007
+ * Note: [🔂] This function is idempotent.
10008
+ *
10009
+ * @public exported from `@promptbook/core`
10010
+ */
10011
+ function padBook(content) {
10012
+ if (!content) {
10013
+ return '\n'.repeat(PADDING_LINES);
10014
+ }
10015
+ const lines = content.split('\n');
10016
+ let trailingEmptyLines = 0;
10017
+ for (let i = lines.length - 1; i >= 0; i--) {
10018
+ const line = lines[i];
10019
+ if (line === undefined) {
10020
+ // Note: This should not happen in reality, but it's here to satisfy TypeScript's noUncheckedIndexedAccess option
10021
+ continue;
10022
+ }
10023
+ if (line.trim() === '') {
10024
+ trailingEmptyLines++;
10025
+ }
10026
+ else {
10027
+ break;
10028
+ }
10029
+ }
10030
+ if (trailingEmptyLines >= PADDING_LINES) {
10031
+ return content;
10032
+ }
10033
+ const linesToAdd = PADDING_LINES - trailingEmptyLines;
10034
+ return (content + '\n'.repeat(linesToAdd));
10035
+ }
10036
+ /**
10037
+ * TODO: [🧠] Maybe export
10038
+ */
10039
+
9923
10040
  /**
9924
10041
  * Removes Markdown (or HTML) comments
9925
10042
  *
@@ -9939,7 +10056,7 @@ function removeMarkdownComments(content) {
9939
10056
  */
9940
10057
  function isFlatPipeline(pipelineString) {
9941
10058
  pipelineString = removeMarkdownComments(pipelineString);
9942
- pipelineString = spaceTrim(pipelineString);
10059
+ pipelineString = spaceTrim$2(pipelineString);
9943
10060
  const isMarkdownBeginningWithHeadline = pipelineString.startsWith('# ');
9944
10061
  //const isLastLineReturnStatement = pipelineString.split('\n').pop()!.split('`').join('').startsWith('->');
9945
10062
  const isBacktickBlockUsed = pipelineString.includes('```');
@@ -9965,6 +10082,7 @@ function deflatePipeline(pipelineString) {
9965
10082
  if (!isFlatPipeline(pipelineString)) {
9966
10083
  return pipelineString;
9967
10084
  }
10085
+ pipelineString = spaceTrim$2(pipelineString);
9968
10086
  const pipelineStringLines = pipelineString.split('\n');
9969
10087
  const potentialReturnStatement = pipelineStringLines.pop();
9970
10088
  let returnStatement;
@@ -9977,19 +10095,19 @@ function deflatePipeline(pipelineString) {
9977
10095
  returnStatement = `-> {${DEFAULT_BOOK_OUTPUT_PARAMETER_NAME}}`;
9978
10096
  pipelineStringLines.push(potentialReturnStatement);
9979
10097
  }
9980
- const prompt = spaceTrim(pipelineStringLines.join('\n'));
10098
+ const prompt = spaceTrim$2(pipelineStringLines.join('\n'));
9981
10099
  let quotedPrompt;
9982
10100
  if (prompt.split('\n').length <= 1) {
9983
10101
  quotedPrompt = `> ${prompt}`;
9984
10102
  }
9985
10103
  else {
9986
- quotedPrompt = spaceTrim((block) => `
10104
+ quotedPrompt = spaceTrim$2((block) => `
9987
10105
  \`\`\`
9988
10106
  ${block(prompt.split('`').join('\\`'))}
9989
10107
  \`\`\`
9990
10108
  `);
9991
10109
  }
9992
- pipelineString = validatePipelineString(spaceTrim((block) => `
10110
+ pipelineString = validatePipelineString(spaceTrim$2((block) => `
9993
10111
  # ${DEFAULT_BOOK_TITLE}
9994
10112
 
9995
10113
  ## Prompt
@@ -9999,7 +10117,7 @@ function deflatePipeline(pipelineString) {
9999
10117
  ${returnStatement}
10000
10118
  `));
10001
10119
  // <- TODO: Maybe use book` notation
10002
- return pipelineString;
10120
+ return padBook(pipelineString);
10003
10121
  }
10004
10122
  /**
10005
10123
  * TODO: Unit test
@@ -10053,7 +10171,7 @@ function extractAllListItemsFromMarkdown(markdown) {
10053
10171
  function extractOneBlockFromMarkdown(markdown) {
10054
10172
  const codeBlocks = extractAllBlocksFromMarkdown(markdown);
10055
10173
  if (codeBlocks.length !== 1) {
10056
- throw new ParseError(spaceTrim((block) => `
10174
+ throw new ParseError(spaceTrim$2((block) => `
10057
10175
  There should be exactly 1 code block in task section, found ${codeBlocks.length} code blocks
10058
10176
 
10059
10177
  ${block(codeBlocks.map((block, i) => `Block ${i + 1}:\n${block.content}`).join('\n\n\n'))}
@@ -10078,7 +10196,7 @@ function parseMarkdownSection(value) {
10078
10196
  }
10079
10197
  const title = lines[0].replace(/^#+\s*/, '');
10080
10198
  const level = (_b = (_a = lines[0].match(/^#+/)) === null || _a === void 0 ? void 0 : _a[0].length) !== null && _b !== void 0 ? _b : 0;
10081
- const content = spaceTrim(lines.slice(1).join('\n'));
10199
+ const content = spaceTrim$2(lines.slice(1).join('\n'));
10082
10200
  if (level < 1 || level > 6) {
10083
10201
  throw new ParseError('Markdown section must have heading level between 1 and 6');
10084
10202
  }
@@ -10106,7 +10224,7 @@ function splitMarkdownIntoSections(markdown) {
10106
10224
  if (buffer.length === 0) {
10107
10225
  return;
10108
10226
  }
10109
- let section = spaceTrim(buffer.join('\n'));
10227
+ let section = spaceTrim$2(buffer.join('\n'));
10110
10228
  if (section === '') {
10111
10229
  return;
10112
10230
  }
@@ -10181,7 +10299,7 @@ function flattenMarkdown(markdown) {
10181
10299
  flattenedMarkdown += `## ${title}` + `\n\n`;
10182
10300
  flattenedMarkdown += content + `\n\n`; // <- [🧠] Maybe 3 new lines?
10183
10301
  }
10184
- return spaceTrim(flattenedMarkdown);
10302
+ return spaceTrim$2(flattenedMarkdown);
10185
10303
  }
10186
10304
  /**
10187
10305
  * TODO: [🏛] This can be part of markdown builder
@@ -10887,6 +11005,7 @@ function $provideFilesystemForNode(options) {
10887
11005
  writeFile,
10888
11006
  readdir,
10889
11007
  mkdir,
11008
+ watch,
10890
11009
  };
10891
11010
  }
10892
11011
  /**
@@ -11174,10 +11293,10 @@ function $registeredLlmToolsMessage() {
11174
11293
  var _a, _b;
11175
11294
  const isMetadataAviailable = $llmToolsMetadataRegister
11176
11295
  .list()
11177
- .find(({ packageName, className }) => metadata.packageName === packageName && metadata.className === className);
11296
+ .some(({ packageName, className }) => metadata.packageName === packageName && metadata.className === className);
11178
11297
  const isInstalled = $llmToolsRegister
11179
11298
  .list()
11180
- .find(({ packageName, className }) => metadata.packageName === packageName && metadata.className === className);
11299
+ .some(({ packageName, className }) => metadata.packageName === packageName && metadata.className === className);
11181
11300
  const isFullyConfigured = ((_a = metadata.envVariables) === null || _a === void 0 ? void 0 : _a.every((envVariableName) => env[envVariableName] !== undefined)) || false;
11182
11301
  const isPartiallyConfigured = ((_b = metadata.envVariables) === null || _b === void 0 ? void 0 : _b.some((envVariableName) => env[envVariableName] !== undefined)) || false;
11183
11302
  // <- Note: [🗨]
@@ -11185,13 +11304,13 @@ function $registeredLlmToolsMessage() {
11185
11304
  });
11186
11305
  const usedEnvMessage = $usedEnvFilename === null ? `Unknown \`.env\` file` : `Used \`.env\` file:\n${$usedEnvFilename}`;
11187
11306
  if (metadata.length === 0) {
11188
- return spaceTrim((block) => `
11307
+ return spaceTrim$2((block) => `
11189
11308
  No LLM providers are available.
11190
11309
 
11191
11310
  ${block(usedEnvMessage)}
11192
11311
  `);
11193
11312
  }
11194
- return spaceTrim((block) => `
11313
+ return spaceTrim$2((block) => `
11195
11314
 
11196
11315
  ${block(usedEnvMessage)}
11197
11316
 
@@ -11237,7 +11356,7 @@ function $registeredLlmToolsMessage() {
11237
11356
  morePieces.push(`Not configured`); // <- Note: Can not be configured via environment variables
11238
11357
  }
11239
11358
  }
11240
- let providerMessage = spaceTrim(`
11359
+ let providerMessage = spaceTrim$2(`
11241
11360
  ${i + 1}) **${title}** \`${className}\` from \`${packageName}\`
11242
11361
  ${morePieces.join('; ')}
11243
11362
  `);
@@ -11399,7 +11518,7 @@ function createLlmToolsFromConfiguration(configuration, options = {}) {
11399
11518
  .find(({ packageName, className }) => llmConfiguration.packageName === packageName && llmConfiguration.className === className);
11400
11519
  if (registeredItem === undefined) {
11401
11520
  // console.log('$llmToolsRegister.list()', $llmToolsRegister.list());
11402
- throw new Error(spaceTrim((block) => `
11521
+ throw new Error(spaceTrim$2((block) => `
11403
11522
  There is no constructor for LLM provider \`${llmConfiguration.className}\` from \`${llmConfiguration.packageName}\`
11404
11523
  Running in ${!$isRunningInBrowser() ? '' : 'browser environment'}${!$isRunningInNode() ? '' : 'node environment'}${!$isRunningInWebWorker() ? '' : 'worker environment'}
11405
11524
 
@@ -11467,14 +11586,14 @@ async function $provideLlmToolsFromEnv(options = {}) {
11467
11586
  const configuration = await $provideLlmToolsConfigurationFromEnv();
11468
11587
  if (configuration.length === 0) {
11469
11588
  if ($llmToolsMetadataRegister.list().length === 0) {
11470
- throw new UnexpectedError(spaceTrim((block) => `
11589
+ throw new UnexpectedError(spaceTrim$2((block) => `
11471
11590
  No LLM tools registered, this is probably a bug in the Promptbook library
11472
11591
 
11473
11592
  ${block($registeredLlmToolsMessage())}}
11474
11593
  `));
11475
11594
  }
11476
11595
  // TODO: [🥃]
11477
- throw new Error(spaceTrim((block) => `
11596
+ throw new Error(spaceTrim$2((block) => `
11478
11597
  No LLM tools found in the environment
11479
11598
 
11480
11599
  ${block($registeredLlmToolsMessage())}}
@@ -11605,6 +11724,9 @@ function nameToUriParts(name) {
11605
11724
  }
11606
11725
 
11607
11726
  /**
11727
+ * Normalizes a given text to PascalCase format.
11728
+ *
11729
+ * Note: [🔂] This function is idempotent.
11608
11730
  *
11609
11731
  * @param text @public exported from `@promptbook/utils`
11610
11732
  * @returns
@@ -11829,8 +11951,8 @@ class JavascriptEvalExecutionTools {
11829
11951
  }
11830
11952
  // Note: [💎]
11831
11953
  // Note: Using direct eval, following variables are in same scope as eval call so they are accessible from inside the evaluated script:
11832
- const spaceTrim$1 = (_) => spaceTrim(_);
11833
- $preserve(spaceTrim$1);
11954
+ const spaceTrim = (_) => spaceTrim$2(_);
11955
+ $preserve(spaceTrim);
11834
11956
  const removeQuotes$1 = removeQuotes;
11835
11957
  $preserve(removeQuotes$1);
11836
11958
  const unwrapResult$1 = unwrapResult;
@@ -11883,7 +12005,7 @@ class JavascriptEvalExecutionTools {
11883
12005
  // TODO: DRY [🍯]
11884
12006
  const buildinFunctions = {
11885
12007
  // TODO: [🍯] DRY all these functions across the file
11886
- spaceTrim: spaceTrim$1,
12008
+ spaceTrim,
11887
12009
  removeQuotes: removeQuotes$1,
11888
12010
  unwrapResult: unwrapResult$1,
11889
12011
  trimEndOfCodeBlock: trimEndOfCodeBlock$1,
@@ -11920,7 +12042,7 @@ class JavascriptEvalExecutionTools {
11920
12042
  .join('\n');
11921
12043
  // script = templateParameters(script, parameters);
11922
12044
  // <- TODO: [🧠][🥳] Should be this is one of two variants how to use parameters in script
11923
- const statementToEvaluate = spaceTrim((block) => `
12045
+ const statementToEvaluate = spaceTrim$2((block) => `
11924
12046
 
11925
12047
  // Build-in functions:
11926
12048
  ${block(buildinFunctionsStatement)}
@@ -11935,7 +12057,7 @@ class JavascriptEvalExecutionTools {
11935
12057
  (()=>{ ${script} })()
11936
12058
  `);
11937
12059
  if (this.options.isVerbose) {
11938
- console.info(spaceTrim((block) => `
12060
+ console.info(spaceTrim$2((block) => `
11939
12061
  🚀 Evaluating ${scriptLanguage} script:
11940
12062
 
11941
12063
  ${block(statementToEvaluate)}`));
@@ -11957,7 +12079,7 @@ class JavascriptEvalExecutionTools {
11957
12079
  To: [PipelineExecutionError: Parameter `{thing}` is not defined],
11958
12080
  */
11959
12081
  if (!statementToEvaluate.includes(undefinedName + '(')) {
11960
- throw new PipelineExecutionError(spaceTrim((block) => `
12082
+ throw new PipelineExecutionError(spaceTrim$2((block) => `
11961
12083
 
11962
12084
  Parameter \`{${undefinedName}}\` is not defined
11963
12085
 
@@ -11979,7 +12101,7 @@ class JavascriptEvalExecutionTools {
11979
12101
  `));
11980
12102
  }
11981
12103
  else {
11982
- throw new PipelineExecutionError(spaceTrim((block) => `
12104
+ throw new PipelineExecutionError(spaceTrim$2((block) => `
11983
12105
  Function ${undefinedName}() is not defined
11984
12106
 
11985
12107
  - Make sure that the function is one of built-in functions
@@ -12071,7 +12193,7 @@ async function isDirectoryExisting(directoryPath, fs) {
12071
12193
  * @param path
12072
12194
  * @param isRecursive
12073
12195
  * @returns List of all files in the directory
12074
- * @private internal function of `createCollectionFromDirectory`
12196
+ * @private internal function of `AgentCollectionInDirectory` and `createPipelineCollectionFromDirectory`
12075
12197
  */
12076
12198
  async function listAllFiles(path, isRecursive, fs) {
12077
12199
  if (!(await isDirectoryExisting(path, fs))) {
@@ -12099,26 +12221,27 @@ async function listAllFiles(path, isRecursive, fs) {
12099
12221
  */
12100
12222
 
12101
12223
  /**
12102
- * Constructs Promptbook from async sources
12224
+ * Constructs `PipelineCollection` from async sources
12225
+ *
12103
12226
  * It can be one of the following:
12104
12227
  * - Promise of array of PipelineJson or PipelineString
12105
12228
  * - Factory function that returns Promise of array of PipelineJson or PipelineString
12106
12229
  *
12107
12230
  * Note: This is useful as internal tool for other constructor functions like
12108
- * `createCollectionFromUrl` or `createCollectionFromDirectory`
12231
+ * `createPipelineCollectionFromUrl` or `createPipelineCollectionFromDirectory`
12109
12232
  * Consider using those functions instead of this one
12110
12233
  *
12111
12234
  * Note: The function does NOT return promise it returns the collection directly which waits for the sources to be resolved
12112
12235
  * when error occurs in given promise or factory function, it is thrown during `listPipelines` or `getPipelineByUrl` call
12113
12236
  *
12114
- * Note: Consider using `createCollectionFromDirectory` or `createCollectionFromUrl`
12237
+ * Note: Consider using `createPipelineCollectionFromDirectory` or `createPipelineCollectionFromUrl`
12115
12238
  *
12116
12239
  * @param promptbookSourcesPromiseOrFactory
12117
12240
  * @returns PipelineCollection
12118
12241
  * @deprecated Do not use, it will became internal tool for other constructor functions
12119
12242
  * @public exported from `@promptbook/core`
12120
12243
  */
12121
- function createCollectionFromPromise(promptbookSourcesPromiseOrFactory) {
12244
+ function createPipelineCollectionFromPromise(promptbookSourcesPromiseOrFactory) {
12122
12245
  let collection = null;
12123
12246
  async function load() {
12124
12247
  if (collection !== null) {
@@ -12129,7 +12252,7 @@ function createCollectionFromPromise(promptbookSourcesPromiseOrFactory) {
12129
12252
  promptbookSourcesPromiseOrFactory = promptbookSourcesPromiseOrFactory();
12130
12253
  }
12131
12254
  const promptbookSources = await promptbookSourcesPromiseOrFactory;
12132
- collection = createCollectionFromJson(...promptbookSources);
12255
+ collection = createPipelineCollectionFromJson(...promptbookSources);
12133
12256
  }
12134
12257
  async function listPipelines() {
12135
12258
  await load();
@@ -12151,7 +12274,7 @@ function createCollectionFromPromise(promptbookSourcesPromiseOrFactory) {
12151
12274
  }
12152
12275
 
12153
12276
  /**
12154
- * Constructs Pipeline from given directory
12277
+ * Constructs `PipelineCollection` from given directory
12155
12278
  *
12156
12279
  * Note: Works only in Node.js environment because it reads the file system
12157
12280
  *
@@ -12161,7 +12284,7 @@ function createCollectionFromPromise(promptbookSourcesPromiseOrFactory) {
12161
12284
  * @returns PipelineCollection
12162
12285
  * @public exported from `@promptbook/node`
12163
12286
  */
12164
- async function createCollectionFromDirectory(rootPath, tools, options) {
12287
+ async function createPipelineCollectionFromDirectory(rootPath, tools, options) {
12165
12288
  if (tools === undefined) {
12166
12289
  tools = await $provideExecutionToolsForNode();
12167
12290
  }
@@ -12180,7 +12303,7 @@ async function createCollectionFromDirectory(rootPath, tools, options) {
12180
12303
  // TODO: [🌗]
12181
12304
  }
12182
12305
  const { isRecursive = true, isVerbose = DEFAULT_IS_VERBOSE, isLazyLoaded = false, isCrashedOnError = true, rootUrl, } = options || {};
12183
- const collection = createCollectionFromPromise(async () => {
12306
+ const collection = createPipelineCollectionFromPromise(async () => {
12184
12307
  if (isVerbose) {
12185
12308
  console.info(colors.cyan(`Creating pipeline collection from path ${rootPath.split('\\').join('/')}`));
12186
12309
  }
@@ -12225,7 +12348,7 @@ async function createCollectionFromDirectory(rootPath, tools, options) {
12225
12348
  catch (error) {
12226
12349
  assertsError(error);
12227
12350
  // TODO: [7] DRY
12228
- const wrappedErrorMessage = spaceTrim((block) => `
12351
+ const wrappedErrorMessage = spaceTrim$2((block) => `
12229
12352
  ${error.name} in pipeline ${fileName.split('\\').join('/')}⁠:
12230
12353
 
12231
12354
  Original error message:
@@ -12260,7 +12383,7 @@ async function createCollectionFromDirectory(rootPath, tools, options) {
12260
12383
  pipeline = { ...pipeline, pipelineUrl };
12261
12384
  }
12262
12385
  else if (!pipeline.pipelineUrl.startsWith(rootUrl)) {
12263
- throw new PipelineUrlError(spaceTrim(`
12386
+ throw new PipelineUrlError(spaceTrim$2(`
12264
12387
  Pipeline with URL ${pipeline.pipelineUrl} is not a child of the root URL ${rootUrl} 🍏
12265
12388
 
12266
12389
  File:
@@ -12298,7 +12421,7 @@ async function createCollectionFromDirectory(rootPath, tools, options) {
12298
12421
  }
12299
12422
  else {
12300
12423
  const existing = collection.get(pipeline.pipelineUrl);
12301
- throw new PipelineUrlError(spaceTrim(`
12424
+ throw new PipelineUrlError(spaceTrim$2(`
12302
12425
  Pipeline with URL ${pipeline.pipelineUrl} is already in the collection 🍏
12303
12426
 
12304
12427
  Conflicting files:
@@ -12316,7 +12439,7 @@ async function createCollectionFromDirectory(rootPath, tools, options) {
12316
12439
  catch (error) {
12317
12440
  assertsError(error);
12318
12441
  // TODO: [7] DRY
12319
- const wrappedErrorMessage = spaceTrim((block) => `
12442
+ const wrappedErrorMessage = spaceTrim$2((block) => `
12320
12443
  ${error.name} in pipeline ${fileName.split('\\').join('/')}⁠:
12321
12444
 
12322
12445
  Original error message:
@@ -12343,7 +12466,7 @@ async function createCollectionFromDirectory(rootPath, tools, options) {
12343
12466
  return collection;
12344
12467
  }
12345
12468
  /**
12346
- * TODO: [🖇] What about symlinks? Maybe option isSymlinksFollowed
12469
+ * TODO: [🖇] What about symlinks? Maybe option `isSymlinksFollowed`
12347
12470
  * TODO: Maybe move from `@promptbook/node` to `@promptbook/core` as we removes direct dependency on `fs`
12348
12471
  */
12349
12472
 
@@ -12373,7 +12496,7 @@ async function $provideScriptingForNode(options) {
12373
12496
  */
12374
12497
  function stringifyPipelineJson(pipeline) {
12375
12498
  if (!isSerializableAsJson(pipeline)) {
12376
- throw new UnexpectedError(spaceTrim(`
12499
+ throw new UnexpectedError(spaceTrim$2(`
12377
12500
  Cannot stringify the pipeline, because it is not serializable as JSON
12378
12501
 
12379
12502
  There can be multiple reasons:
@@ -12508,5 +12631,5 @@ async function $execCommands({ commands, cwd, crashOnError, }) {
12508
12631
  * Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
12509
12632
  */
12510
12633
 
12511
- export { $execCommand, $execCommands, $provideExecutablesForNode, $provideExecutionToolsForNode, $provideFilesystemForNode, $provideLlmToolsConfigurationFromEnv, $provideLlmToolsFromEnv, $provideScrapersForNode, $provideScriptingForNode, BOOK_LANGUAGE_VERSION, FileCacheStorage, PROMPTBOOK_ENGINE_VERSION, createCollectionFromDirectory };
12634
+ export { $execCommand, $execCommands, $provideExecutablesForNode, $provideExecutionToolsForNode, $provideFilesystemForNode, $provideLlmToolsConfigurationFromEnv, $provideLlmToolsFromEnv, $provideScrapersForNode, $provideScriptingForNode, BOOK_LANGUAGE_VERSION, FileCacheStorage, PROMPTBOOK_ENGINE_VERSION, createPipelineCollectionFromDirectory };
12512
12635
  //# sourceMappingURL=index.es.js.map