@promptbook/wizard 0.113.0-1 → 0.113.0-10

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 (244) hide show
  1. package/README.md +1 -17
  2. package/esm/index.es.js +1121 -1096
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/src/_packages/types.index.d.ts +2 -2
  5. package/esm/src/avatars/renderAvatarVisualAsciiArt.d.ts +98 -0
  6. package/esm/src/avatars/visuals/octopus3dAvatarVisualShared.d.ts +1 -1
  7. package/esm/src/book-components/BookEditor/BookEditorMonacoUploadPanel.d.ts +1 -1
  8. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/bookEditorMonacoUploadTypes.d.ts +120 -0
  9. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/clearScheduledTimer.d.ts +6 -0
  10. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/enqueueFilesForUpload.d.ts +26 -0
  11. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadEditorSync.d.ts +23 -0
  12. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadItemsState.d.ts +21 -0
  13. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadProgressQueue.d.ts +12 -0
  14. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadQueue.d.ts +27 -0
  15. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/useCompletedUploadsAutoClear.d.ts +12 -0
  16. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads.d.ts +5 -58
  17. package/esm/src/book-components/Chat/Chat/ChatImageAttachmentModal.d.ts +25 -0
  18. package/esm/src/book-components/Chat/Chat/ChatInputArea.d.ts +3 -0
  19. package/esm/src/book-components/Chat/Chat/ChatMessageAttachments.d.ts +27 -0
  20. package/esm/src/book-components/Chat/Chat/ChatMessageItem.d.ts +1 -1
  21. package/esm/src/book-components/Chat/Chat/ChatMessageList.d.ts +1 -0
  22. package/esm/src/book-components/Chat/Chat/ChatProps.d.ts +8 -0
  23. package/esm/src/book-components/Chat/Chat/CitationIframePreview.d.ts +1 -1
  24. package/esm/src/book-components/Chat/Chat/CitationIframePreview.test.d.ts +2 -0
  25. package/esm/src/book-components/Chat/Chat/insertDictationChunk.d.ts +1 -1
  26. package/esm/src/book-components/Chat/Chat/insertDictationChunk.test.d.ts +1 -0
  27. package/esm/src/book-components/Chat/Chat/learnDictationDictionary.test.d.ts +1 -0
  28. package/esm/src/book-components/Chat/Chat/refineFinalDictationChunk.test.d.ts +1 -0
  29. package/esm/src/book-components/Chat/Chat/useChatInputAreaComposer.d.ts +12 -0
  30. package/esm/src/book-components/Chat/Chat/useChatInputAreaComposer.draftMessage.test.d.ts +2 -0
  31. package/esm/src/book-components/Chat/utils/isVisibleChatToolCall.d.ts +1 -1
  32. package/esm/src/book-components/Chat/utils/parseMessageButtons.d.ts +16 -2
  33. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/AGENTS_SERVER_BUILD_CACHE_FILENAME.d.ts +6 -0
  34. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/AGENTS_SERVER_BUILD_CACHE_VERSION.d.ts +6 -0
  35. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/AGENTS_SERVER_NEXT_BUILD_ID_FILENAME.d.ts +6 -0
  36. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/AgentsServerBuildCache.d.ts +10 -0
  37. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/AgentsServerBuildCacheOptions.d.ts +10 -0
  38. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/NODE_MODULES_DIRECTORY_NAME.d.ts +6 -0
  39. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/PreparedAgentsServerRuntime.d.ts +18 -0
  40. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerBuildSourceFingerprint.d.ts +6 -0
  41. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerRuntimeEnvironment.d.ts +28 -0
  42. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/ensureAgentsServerBuild.d.ts +19 -0
  43. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/getAgentsServerBuildInputRelativePaths.d.ts +11 -0
  44. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerAppPath.d.ts +6 -0
  45. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerAppPathMaterialized.d.ts +6 -0
  46. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerBuildCacheCurrent.d.ts +7 -0
  47. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerBuildInputTestFile.d.ts +6 -0
  48. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isExcludedAgentsServerBuildInputDirectoryName.d.ts +6 -0
  49. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isExcludedAgentsServerBuildInputPath.d.ts +6 -0
  50. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isExcludedAgentsServerRuntimeSourcePath.d.ts +6 -0
  51. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isFile.d.ts +6 -0
  52. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isPathInsideNodeModules.d.ts +6 -0
  53. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/normalizeAgentsServerBuildInputPath.d.ts +6 -0
  54. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/prepareAgentsServerRuntime.d.ts +9 -0
  55. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/readAgentsServerBuildCache.d.ts +8 -0
  56. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/resolveAgentsServerAppPath.d.ts +6 -0
  57. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/resolveAgentsServerBuildAppPath.d.ts +9 -0
  58. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/resolveAgentsServerBuildOutputPath.d.ts +7 -0
  59. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/resolveNextCliPath.d.ts +6 -0
  60. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/resolveNodeModulesPath.d.ts +6 -0
  61. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/runNextBuild.d.ts +12 -0
  62. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/shouldCopyAgentsServerRuntimePath.d.ts +6 -0
  63. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/synchronizeMaterializedAgentsServerRuntime.d.ts +11 -0
  64. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/writeAgentsServerBuildCache.d.ts +7 -0
  65. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +8 -109
  66. package/esm/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.d.ts +1 -1
  67. package/esm/src/cli/cli-commands/agents-server/ensureAgentsServerGitignoreFile.d.ts +1 -1
  68. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerChildEnvironment.d.ts +16 -0
  69. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerLogStreams.d.ts +30 -0
  70. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerRuntimePaths.d.ts +19 -0
  71. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerSupervisorState.d.ts +37 -0
  72. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/LocalAgentRunnerLimits.d.ts +9 -0
  73. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/PreparedAgentsServerLaunch.d.ts +13 -0
  74. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/StartAgentsServerOptions.d.ts +24 -0
  75. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/createInternalRouteErrorMessage.d.ts +6 -0
  76. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/createLocalAgentRunOptions.d.ts +9 -0
  77. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/forwardChildOutput.d.ts +13 -0
  78. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/loadAgentsServerProjectEnvironment.d.ts +6 -0
  79. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/prepareAgentsServerLaunch.d.ts +18 -0
  80. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/readInternalRouteErrorDetails.d.ts +6 -0
  81. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/resolveAgentsServerChildHostname.d.ts +7 -0
  82. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/startNextServer.d.ts +20 -0
  83. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/startUserChatJobWorkerPump.d.ts +15 -0
  84. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/stopChildProcess.d.ts +8 -0
  85. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/waitForLocalAgentRunnerLimits.d.ts +16 -0
  86. package/esm/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +3 -30
  87. package/esm/src/cli/cli-commands/common/createPositiveIntegerOptionParser.d.ts +10 -0
  88. package/esm/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +1 -1
  89. package/esm/src/collection/agent-collection/CreateAgentInput.d.ts +1 -1
  90. package/esm/src/collection/agent-collection/constructors/agent-collection-in-supabase/prepareAgentSourceForPersistence.d.ts +1 -1
  91. package/esm/src/commitments/META/META.d.ts +2 -2
  92. package/esm/src/commitments/META_AVATAR/META_AVATAR.d.ts +9 -4
  93. package/esm/src/commitments/index.d.ts +1 -1
  94. package/esm/src/conversion/validation/validatePipeline/createPipelineValidationContext.d.ts +16 -0
  95. package/esm/src/conversion/validation/validatePipeline/validatePipelineCollectionsStructure.d.ts +7 -0
  96. package/esm/src/conversion/validation/validatePipeline/validatePipelineDependencyResolution.d.ts +7 -0
  97. package/esm/src/conversion/validation/validatePipeline/validatePipelineMetadata.d.ts +7 -0
  98. package/esm/src/conversion/validation/validatePipeline/validatePipelineParameters.d.ts +7 -0
  99. package/esm/src/conversion/validation/validatePipeline/validatePipelineTasks.d.ts +7 -0
  100. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/RegisteredLlmToolsMessageContext.d.ts +46 -0
  101. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/USED_ENV_FILENAME.d.ts +11 -0
  102. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolConfigurationStatusMessage.d.ts +7 -0
  103. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolEntryKey.d.ts +7 -0
  104. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolInstallationStatusMessage.d.ts +7 -0
  105. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolStatus.d.ts +14 -0
  106. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolsMessageContext.d.ts +7 -0
  107. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/getAvailableRegisteredLlmToolsEnvironmentVariables.d.ts +7 -0
  108. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/getRegisteredLlmToolRegisters.d.ts +7 -0
  109. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/hasRegisteredLlmToolEntry.d.ts +7 -0
  110. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/listRegisteredLlmToolEntries.d.ts +9 -0
  111. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/listRegisteredLlmToolStatuses.d.ts +7 -0
  112. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderAvailableRegisteredLlmTools.d.ts +7 -0
  113. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderNoRegisteredLlmToolsMessage.d.ts +7 -0
  114. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderRegisteredLlmToolsMessage.d.ts +8 -0
  115. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderRelevantRegisteredLlmToolsEnvironmentVariables.d.ts +7 -0
  116. package/esm/src/utils/agent-message-runtime/agentMessageRuntimePaths.d.ts +24 -0
  117. package/esm/src/utils/agents/resolveAgentAvatarImageUrl.d.ts +2 -2
  118. package/esm/src/utils/ascii-art/$detectTerminalAnsiColorDepth.d.ts +15 -0
  119. package/esm/src/utils/ascii-art/convertImageDataToAsciiArt.d.ts +80 -0
  120. package/esm/src/utils/color/Color.d.ts +1 -1
  121. package/esm/src/version.d.ts +1 -1
  122. package/package.json +2 -2
  123. package/umd/index.umd.js +1121 -1096
  124. package/umd/index.umd.js.map +1 -1
  125. package/umd/src/_packages/types.index.d.ts +2 -2
  126. package/umd/src/avatars/renderAvatarVisualAsciiArt.d.ts +98 -0
  127. package/umd/src/avatars/visuals/octopus3dAvatarVisualShared.d.ts +1 -1
  128. package/umd/src/book-components/BookEditor/BookEditorMonacoUploadPanel.d.ts +1 -1
  129. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/bookEditorMonacoUploadTypes.d.ts +120 -0
  130. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/clearScheduledTimer.d.ts +6 -0
  131. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/enqueueFilesForUpload.d.ts +26 -0
  132. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadEditorSync.d.ts +23 -0
  133. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadItemsState.d.ts +21 -0
  134. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadProgressQueue.d.ts +12 -0
  135. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadQueue.d.ts +27 -0
  136. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/useCompletedUploadsAutoClear.d.ts +12 -0
  137. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads.d.ts +5 -58
  138. package/umd/src/book-components/Chat/Chat/ChatImageAttachmentModal.d.ts +25 -0
  139. package/umd/src/book-components/Chat/Chat/ChatInputArea.d.ts +3 -0
  140. package/umd/src/book-components/Chat/Chat/ChatMessageAttachments.d.ts +27 -0
  141. package/umd/src/book-components/Chat/Chat/ChatMessageItem.d.ts +1 -1
  142. package/umd/src/book-components/Chat/Chat/ChatMessageList.d.ts +1 -0
  143. package/umd/src/book-components/Chat/Chat/ChatProps.d.ts +8 -0
  144. package/umd/src/book-components/Chat/Chat/CitationIframePreview.d.ts +1 -1
  145. package/umd/src/book-components/Chat/Chat/CitationIframePreview.test.d.ts +2 -0
  146. package/umd/src/book-components/Chat/Chat/insertDictationChunk.d.ts +1 -1
  147. package/umd/src/book-components/Chat/Chat/insertDictationChunk.test.d.ts +1 -0
  148. package/umd/src/book-components/Chat/Chat/learnDictationDictionary.test.d.ts +1 -0
  149. package/umd/src/book-components/Chat/Chat/refineFinalDictationChunk.test.d.ts +1 -0
  150. package/umd/src/book-components/Chat/Chat/useChatInputAreaComposer.d.ts +12 -0
  151. package/umd/src/book-components/Chat/Chat/useChatInputAreaComposer.draftMessage.test.d.ts +2 -0
  152. package/umd/src/book-components/Chat/utils/isVisibleChatToolCall.d.ts +1 -1
  153. package/umd/src/book-components/Chat/utils/parseMessageButtons.d.ts +16 -2
  154. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/AGENTS_SERVER_BUILD_CACHE_FILENAME.d.ts +6 -0
  155. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/AGENTS_SERVER_BUILD_CACHE_VERSION.d.ts +6 -0
  156. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/AGENTS_SERVER_NEXT_BUILD_ID_FILENAME.d.ts +6 -0
  157. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/AgentsServerBuildCache.d.ts +10 -0
  158. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/AgentsServerBuildCacheOptions.d.ts +10 -0
  159. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/NODE_MODULES_DIRECTORY_NAME.d.ts +6 -0
  160. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/PreparedAgentsServerRuntime.d.ts +18 -0
  161. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerBuildSourceFingerprint.d.ts +6 -0
  162. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerRuntimeEnvironment.d.ts +28 -0
  163. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/ensureAgentsServerBuild.d.ts +19 -0
  164. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/getAgentsServerBuildInputRelativePaths.d.ts +11 -0
  165. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerAppPath.d.ts +6 -0
  166. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerAppPathMaterialized.d.ts +6 -0
  167. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerBuildCacheCurrent.d.ts +7 -0
  168. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerBuildInputTestFile.d.ts +6 -0
  169. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isExcludedAgentsServerBuildInputDirectoryName.d.ts +6 -0
  170. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isExcludedAgentsServerBuildInputPath.d.ts +6 -0
  171. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isExcludedAgentsServerRuntimeSourcePath.d.ts +6 -0
  172. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isFile.d.ts +6 -0
  173. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isPathInsideNodeModules.d.ts +6 -0
  174. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/normalizeAgentsServerBuildInputPath.d.ts +6 -0
  175. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/prepareAgentsServerRuntime.d.ts +9 -0
  176. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/readAgentsServerBuildCache.d.ts +8 -0
  177. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/resolveAgentsServerAppPath.d.ts +6 -0
  178. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/resolveAgentsServerBuildAppPath.d.ts +9 -0
  179. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/resolveAgentsServerBuildOutputPath.d.ts +7 -0
  180. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/resolveNextCliPath.d.ts +6 -0
  181. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/resolveNodeModulesPath.d.ts +6 -0
  182. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/runNextBuild.d.ts +12 -0
  183. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/shouldCopyAgentsServerRuntimePath.d.ts +6 -0
  184. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/synchronizeMaterializedAgentsServerRuntime.d.ts +11 -0
  185. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/writeAgentsServerBuildCache.d.ts +7 -0
  186. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +8 -109
  187. package/umd/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.d.ts +1 -1
  188. package/umd/src/cli/cli-commands/agents-server/ensureAgentsServerGitignoreFile.d.ts +1 -1
  189. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerChildEnvironment.d.ts +16 -0
  190. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerLogStreams.d.ts +30 -0
  191. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerRuntimePaths.d.ts +19 -0
  192. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerSupervisorState.d.ts +37 -0
  193. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/LocalAgentRunnerLimits.d.ts +9 -0
  194. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/PreparedAgentsServerLaunch.d.ts +13 -0
  195. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/StartAgentsServerOptions.d.ts +24 -0
  196. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/createInternalRouteErrorMessage.d.ts +6 -0
  197. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/createLocalAgentRunOptions.d.ts +9 -0
  198. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/forwardChildOutput.d.ts +13 -0
  199. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/loadAgentsServerProjectEnvironment.d.ts +6 -0
  200. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/prepareAgentsServerLaunch.d.ts +18 -0
  201. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/readInternalRouteErrorDetails.d.ts +6 -0
  202. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/resolveAgentsServerChildHostname.d.ts +7 -0
  203. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/startNextServer.d.ts +20 -0
  204. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/startUserChatJobWorkerPump.d.ts +15 -0
  205. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/stopChildProcess.d.ts +8 -0
  206. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/waitForLocalAgentRunnerLimits.d.ts +16 -0
  207. package/umd/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +3 -30
  208. package/umd/src/cli/cli-commands/common/createPositiveIntegerOptionParser.d.ts +10 -0
  209. package/umd/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +1 -1
  210. package/umd/src/collection/agent-collection/CreateAgentInput.d.ts +1 -1
  211. package/umd/src/collection/agent-collection/constructors/agent-collection-in-supabase/prepareAgentSourceForPersistence.d.ts +1 -1
  212. package/umd/src/commitments/META/META.d.ts +2 -2
  213. package/umd/src/commitments/META_AVATAR/META_AVATAR.d.ts +9 -4
  214. package/umd/src/commitments/index.d.ts +1 -1
  215. package/umd/src/conversion/validation/validatePipeline/createPipelineValidationContext.d.ts +16 -0
  216. package/umd/src/conversion/validation/validatePipeline/validatePipelineCollectionsStructure.d.ts +7 -0
  217. package/umd/src/conversion/validation/validatePipeline/validatePipelineDependencyResolution.d.ts +7 -0
  218. package/umd/src/conversion/validation/validatePipeline/validatePipelineMetadata.d.ts +7 -0
  219. package/umd/src/conversion/validation/validatePipeline/validatePipelineParameters.d.ts +7 -0
  220. package/umd/src/conversion/validation/validatePipeline/validatePipelineTasks.d.ts +7 -0
  221. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/RegisteredLlmToolsMessageContext.d.ts +46 -0
  222. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/USED_ENV_FILENAME.d.ts +11 -0
  223. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolConfigurationStatusMessage.d.ts +7 -0
  224. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolEntryKey.d.ts +7 -0
  225. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolInstallationStatusMessage.d.ts +7 -0
  226. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolStatus.d.ts +14 -0
  227. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolsMessageContext.d.ts +7 -0
  228. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/getAvailableRegisteredLlmToolsEnvironmentVariables.d.ts +7 -0
  229. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/getRegisteredLlmToolRegisters.d.ts +7 -0
  230. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/hasRegisteredLlmToolEntry.d.ts +7 -0
  231. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/listRegisteredLlmToolEntries.d.ts +9 -0
  232. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/listRegisteredLlmToolStatuses.d.ts +7 -0
  233. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderAvailableRegisteredLlmTools.d.ts +7 -0
  234. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderNoRegisteredLlmToolsMessage.d.ts +7 -0
  235. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderRegisteredLlmToolsMessage.d.ts +8 -0
  236. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderRelevantRegisteredLlmToolsEnvironmentVariables.d.ts +7 -0
  237. package/umd/src/utils/agent-message-runtime/agentMessageRuntimePaths.d.ts +24 -0
  238. package/umd/src/utils/agents/resolveAgentAvatarImageUrl.d.ts +2 -2
  239. package/umd/src/utils/ascii-art/$detectTerminalAnsiColorDepth.d.ts +15 -0
  240. package/umd/src/utils/ascii-art/convertImageDataToAsciiArt.d.ts +80 -0
  241. package/umd/src/utils/color/Color.d.ts +1 -1
  242. package/umd/src/version.d.ts +1 -1
  243. package/esm/src/book-components/Chat/utils/livePagePreviewConstants.d.ts +0 -12
  244. package/umd/src/book-components/Chat/utils/livePagePreviewConstants.d.ts +0 -12
package/esm/index.es.js CHANGED
@@ -38,7 +38,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
38
38
  * @generated
39
39
  * @see https://github.com/webgptorg/promptbook
40
40
  */
41
- const PROMPTBOOK_ENGINE_VERSION = '0.113.0-1';
41
+ const PROMPTBOOK_ENGINE_VERSION = '0.113.0-10';
42
42
  /**
43
43
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
44
44
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -115,6 +115,127 @@ function take(initialValue) {
115
115
  });
116
116
  }
117
117
 
118
+ /**
119
+ * Validates that a channel value is a valid number within the range of 0 to 255.
120
+ * Throws an error if the value is not valid.
121
+ *
122
+ * @param channelName - The name of the channel being validated.
123
+ * @param value - The value of the channel to validate.
124
+ * @throws Will throw an error if the value is not a valid channel number.
125
+ *
126
+ * @private util of `@promptbook/color`
127
+ */
128
+ function checkChannelValue(channelName, value) {
129
+ if (typeof value !== 'number') {
130
+ throw new Error(`${channelName} channel value is not number but ${typeof value}`);
131
+ }
132
+ if (isNaN(value)) {
133
+ throw new Error(`${channelName} channel value is NaN`);
134
+ }
135
+ if (Math.round(value) !== value) {
136
+ throw new Error(`${channelName} channel is not whole number, it is ${value}`);
137
+ }
138
+ if (value < 0) {
139
+ throw new Error(`${channelName} channel is lower than 0, it is ${value}`);
140
+ }
141
+ if (value > 255) {
142
+ throw new Error(`${channelName} channel is greater than 255, it is ${value}`);
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Shared immutable channel storage and serialization helpers for `Color`.
148
+ *
149
+ * @private base class of Color
150
+ */
151
+ class ColorValue {
152
+ constructor(red, green, blue, alpha = 255) {
153
+ this.red = red;
154
+ this.green = green;
155
+ this.blue = blue;
156
+ this.alpha = alpha;
157
+ checkChannelValue('Red', red);
158
+ checkChannelValue('Green', green);
159
+ checkChannelValue('Blue', blue);
160
+ checkChannelValue('Alpha', alpha);
161
+ }
162
+ /**
163
+ * Shortcut for `red` property
164
+ * Number from 0 to 255
165
+ * @alias red
166
+ */
167
+ get r() {
168
+ return this.red;
169
+ }
170
+ /**
171
+ * Shortcut for `green` property
172
+ * Number from 0 to 255
173
+ * @alias green
174
+ */
175
+ get g() {
176
+ return this.green;
177
+ }
178
+ /**
179
+ * Shortcut for `blue` property
180
+ * Number from 0 to 255
181
+ * @alias blue
182
+ */
183
+ get b() {
184
+ return this.blue;
185
+ }
186
+ /**
187
+ * Shortcut for `alpha` property
188
+ * Number from 0 (transparent) to 255 (opaque)
189
+ * @alias alpha
190
+ */
191
+ get a() {
192
+ return this.alpha;
193
+ }
194
+ /**
195
+ * Shortcut for `alpha` property
196
+ * Number from 0 (transparent) to 255 (opaque)
197
+ * @alias alpha
198
+ */
199
+ get opacity() {
200
+ return this.alpha;
201
+ }
202
+ /**
203
+ * Shortcut for 1-`alpha` property
204
+ */
205
+ get transparency() {
206
+ return 255 - this.alpha;
207
+ }
208
+ clone() {
209
+ return take(this.createColor(this.red, this.green, this.blue, this.alpha));
210
+ }
211
+ toString() {
212
+ return this.toHex();
213
+ }
214
+ toHex() {
215
+ if (this.alpha === 255) {
216
+ return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
217
+ .toString(16)
218
+ .padStart(2, '0')}`;
219
+ }
220
+ else {
221
+ return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
222
+ .toString(16)
223
+ .padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
224
+ }
225
+ }
226
+ toRgb() {
227
+ if (this.alpha === 255) {
228
+ return `rgb(${this.red}, ${this.green}, ${this.blue})`;
229
+ }
230
+ else {
231
+ return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
232
+ }
233
+ }
234
+ toHsl() {
235
+ throw new Error(`Getting HSL is not implemented`);
236
+ }
237
+ }
238
+
118
239
  /**
119
240
  * 🎨 List of all 140 color names which are supported by CSS
120
241
  *
@@ -274,127 +395,6 @@ const CSS_COLORS = {
274
395
  };
275
396
  // Note: [💞] Ignore a discrepancy between file name and entity name
276
397
 
277
- /**
278
- * Validates that a channel value is a valid number within the range of 0 to 255.
279
- * Throws an error if the value is not valid.
280
- *
281
- * @param channelName - The name of the channel being validated.
282
- * @param value - The value of the channel to validate.
283
- * @throws Will throw an error if the value is not a valid channel number.
284
- *
285
- * @private util of `@promptbook/color`
286
- */
287
- function checkChannelValue(channelName, value) {
288
- if (typeof value !== 'number') {
289
- throw new Error(`${channelName} channel value is not number but ${typeof value}`);
290
- }
291
- if (isNaN(value)) {
292
- throw new Error(`${channelName} channel value is NaN`);
293
- }
294
- if (Math.round(value) !== value) {
295
- throw new Error(`${channelName} channel is not whole number, it is ${value}`);
296
- }
297
- if (value < 0) {
298
- throw new Error(`${channelName} channel is lower than 0, it is ${value}`);
299
- }
300
- if (value > 255) {
301
- throw new Error(`${channelName} channel is greater than 255, it is ${value}`);
302
- }
303
- }
304
-
305
- /**
306
- * Shared immutable channel storage and serialization helpers for `Color`.
307
- *
308
- * @private base class of Color
309
- */
310
- class ColorValue {
311
- constructor(red, green, blue, alpha = 255) {
312
- this.red = red;
313
- this.green = green;
314
- this.blue = blue;
315
- this.alpha = alpha;
316
- checkChannelValue('Red', red);
317
- checkChannelValue('Green', green);
318
- checkChannelValue('Blue', blue);
319
- checkChannelValue('Alpha', alpha);
320
- }
321
- /**
322
- * Shortcut for `red` property
323
- * Number from 0 to 255
324
- * @alias red
325
- */
326
- get r() {
327
- return this.red;
328
- }
329
- /**
330
- * Shortcut for `green` property
331
- * Number from 0 to 255
332
- * @alias green
333
- */
334
- get g() {
335
- return this.green;
336
- }
337
- /**
338
- * Shortcut for `blue` property
339
- * Number from 0 to 255
340
- * @alias blue
341
- */
342
- get b() {
343
- return this.blue;
344
- }
345
- /**
346
- * Shortcut for `alpha` property
347
- * Number from 0 (transparent) to 255 (opaque)
348
- * @alias alpha
349
- */
350
- get a() {
351
- return this.alpha;
352
- }
353
- /**
354
- * Shortcut for `alpha` property
355
- * Number from 0 (transparent) to 255 (opaque)
356
- * @alias alpha
357
- */
358
- get opacity() {
359
- return this.alpha;
360
- }
361
- /**
362
- * Shortcut for 1-`alpha` property
363
- */
364
- get transparency() {
365
- return 255 - this.alpha;
366
- }
367
- clone() {
368
- return take(this.createColor(this.red, this.green, this.blue, this.alpha));
369
- }
370
- toString() {
371
- return this.toHex();
372
- }
373
- toHex() {
374
- if (this.alpha === 255) {
375
- return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
376
- .toString(16)
377
- .padStart(2, '0')}`;
378
- }
379
- else {
380
- return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
381
- .toString(16)
382
- .padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
383
- }
384
- }
385
- toRgb() {
386
- if (this.alpha === 255) {
387
- return `rgb(${this.red}, ${this.green}, ${this.blue})`;
388
- }
389
- else {
390
- return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
391
- }
392
- }
393
- toHsl() {
394
- throw new Error(`Getting HSL is not implemented`);
395
- }
396
- }
397
-
398
398
  /**
399
399
  * Checks if the given value is a valid hex color string
400
400
  *
@@ -11463,140 +11463,10 @@ function pipelineJsonToString(pipelineJson) {
11463
11463
  // TODO: [🏛] Escape all
11464
11464
  // TODO: [🧠] Should be in generated .book.md file GENERATOR_WARNING
11465
11465
 
11466
- /**
11467
- * Tests if given string is valid semantic version
11468
- *
11469
- * Note: There are two similar functions:
11470
- * - `isValidSemanticVersion` which tests any semantic version
11471
- * - `isValidPromptbookVersion` *(this one)* which tests just Promptbook versions
11472
- *
11473
- * @public exported from `@promptbook/utils`
11474
- */
11475
- function isValidSemanticVersion(version) {
11476
- if (typeof version !== 'string') {
11477
- return false;
11478
- }
11479
- if (version.startsWith('0.0.0')) {
11480
- return false;
11481
- }
11482
- return /^\d+\.\d+\.\d+(-\d+)?$/i.test(version);
11483
- }
11484
-
11485
- /**
11486
- * Tests if given string is valid promptbook version
11487
- * It looks into list of known promptbook versions.
11488
- *
11489
- * Note: When you are using for example promptbook 2.0.0 and there already is promptbook 3.0.0 it don`t know about it.
11490
- * Note: There are two similar functions:
11491
- * - `isValidSemanticVersion` which tests any semantic version
11492
- * - `isValidPromptbookVersion` *(this one)* which tests just Promptbook versions
11493
- *
11494
- * @see https://www.npmjs.com/package/promptbook?activeTab=versions
11495
- *
11496
- * @public exported from `@promptbook/utils`
11497
- */
11498
- function isValidPromptbookVersion(version) {
11499
- if (!isValidSemanticVersion(version)) {
11500
- return false;
11501
- }
11502
- if ( /* version === '1.0.0' || */version === '2.0.0' || version === '3.0.0') {
11503
- return false;
11504
- }
11505
- // <- TODO: [main] !!3 Check isValidPromptbookVersion against PROMPTBOOK_ENGINE_VERSIONS
11506
- return true;
11507
- }
11508
-
11509
- /**
11510
- * Tests if given string is valid pipeline URL URL.
11511
- *
11512
- * Note: There are few similar functions:
11513
- * - `isValidUrl` which tests any URL
11514
- * - `isValidAgentUrl` which tests just agent URL
11515
- * - `isValidPipelineUrl` *(this one)* which tests just pipeline URL
11516
- *
11517
- * @public exported from `@promptbook/utils`
11518
- */
11519
- function isValidPipelineUrl(url) {
11520
- if (!isValidUrl(url)) {
11521
- return false;
11522
- }
11523
- if (!url.startsWith('https://') && !url.startsWith('http://') /* <- Note: [👣] */) {
11524
- return false;
11525
- }
11526
- if (url.includes('#')) {
11527
- // TODO: [🐠]
11528
- return false;
11529
- }
11530
- /*
11531
- Note: [👣][🧠] Is it secure to allow pipeline URLs on private and unsecured networks?
11532
- if (isUrlOnPrivateNetwork(url)) {
11533
- return false;
11534
- }
11535
- */
11536
- return true;
11537
- }
11538
- // TODO: [🐠] Maybe more info why the URL is invalid
11539
-
11540
- /**
11541
- * Validates PipelineJson if it is logically valid
11542
- *
11543
- * It checks:
11544
- * - if it has correct parameters dependency
11545
- *
11546
- * It does NOT check:
11547
- * - if it is valid json
11548
- * - if it is meaningful
11549
- *
11550
- * Note: [🔂] This function is idempotent.
11551
- *
11552
- * @param pipeline valid or invalid PipelineJson
11553
- * @returns the same pipeline if it is logically valid
11554
- * @throws {PipelineLogicError} on logical error in the pipeline
11555
- *
11556
- * @public exported from `@promptbook/core`
11557
- */
11558
- function validatePipeline(pipeline) {
11559
- if (IS_PIPELINE_LOGIC_VALIDATED) {
11560
- validatePipeline_InnerFunction(pipeline);
11561
- }
11562
- else {
11563
- try {
11564
- validatePipeline_InnerFunction(pipeline);
11565
- }
11566
- catch (error) {
11567
- if (!(error instanceof PipelineLogicError)) {
11568
- throw error;
11569
- }
11570
- console.error(spaceTrim$1((block) => `
11571
- Pipeline is not valid but logic errors are temporarily disabled via \`IS_PIPELINE_LOGIC_VALIDATED\`
11572
-
11573
- ${block(error.message)}
11574
- `));
11575
- }
11576
- }
11577
- return pipeline;
11578
- }
11579
- /**
11580
- * Validates pipeline inner function.
11581
- *
11582
- * @private internal function for `validatePipeline`
11583
- */
11584
- function validatePipeline_InnerFunction(pipeline) {
11585
- // TODO: [🧠] Maybe test if promptbook is a promise and make specific error case for that
11586
- const context = createPipelineValidationContext(pipeline);
11587
- validatePipelineMetadata(context);
11588
- validatePipelineCollectionsStructure(context);
11589
- validatePipelineParameters(context);
11590
- validatePipelineTasks(context);
11591
- validatePipelineDependencyResolution(context);
11592
- // Note: Check that formfactor is corresponding to the pipeline interface
11593
- // TODO: !!6 Implement this
11594
- // pipeline.formfactorName
11595
- }
11596
11466
  /**
11597
11467
  * Creates the shared validation context for one pipeline.
11598
11468
  *
11599
- * @private internal utility of `validatePipeline`
11469
+ * @private function of `validatePipeline`
11600
11470
  */
11601
11471
  function createPipelineValidationContext(pipeline) {
11602
11472
  return {
@@ -11620,52 +11490,61 @@ function getPipelineIdentification$1(pipeline) {
11620
11490
  }
11621
11491
  return pipelineIdentificationParts.join('\n');
11622
11492
  }
11623
- /**
11624
- * Validates pipeline-level metadata fields.
11625
- *
11626
- * @private internal step of `validatePipeline`
11627
- */
11628
- function validatePipelineMetadata({ pipeline, pipelineIdentification }) {
11629
- validatePipelineUrl(pipeline, pipelineIdentification);
11630
- validatePipelineBookVersion(pipeline, pipelineIdentification);
11631
- }
11493
+
11632
11494
  /**
11633
11495
  * Validates that the expected top-level collections have array structure.
11634
11496
  *
11635
- * @private internal step of `validatePipeline`
11497
+ * @private function of `validatePipeline`
11636
11498
  */
11637
- function validatePipelineCollectionsStructure({ pipeline, pipelineIdentification }) {
11499
+ function validatePipelineCollectionsStructure({ pipeline, pipelineIdentification, }) {
11638
11500
  validatePipelineParametersCollection(pipeline, pipelineIdentification);
11639
11501
  validatePipelineTasksCollection(pipeline, pipelineIdentification);
11640
11502
  }
11641
11503
  /**
11642
- * Validates all pipeline parameter declarations.
11504
+ * Validates that `pipeline.parameters` is an array.
11643
11505
  *
11644
- * @private internal step of `validatePipeline`
11506
+ * @private internal utility of `validatePipelineCollectionsStructure`
11645
11507
  */
11646
- function validatePipelineParameters({ pipeline, pipelineIdentification }) {
11647
- for (const parameter of pipeline.parameters) {
11648
- validatePipelineParameter(parameter, pipeline, pipelineIdentification);
11508
+ function validatePipelineParametersCollection(pipeline, pipelineIdentification) {
11509
+ // TODO: [🧠] Maybe do here some proper JSON-schema / ZOD checking
11510
+ if (Array.isArray(pipeline.parameters)) {
11511
+ return;
11649
11512
  }
11513
+ // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
11514
+ throw new ParseError(spaceTrim$1((block) => `
11515
+ Pipeline is valid JSON but with wrong structure
11516
+
11517
+ \`PipelineJson.parameters\` expected to be an array, but got ${typeof pipeline.parameters}
11518
+
11519
+ ${block(pipelineIdentification)}
11520
+ `));
11650
11521
  }
11651
11522
  /**
11652
- * Validates all pipeline tasks and their per-task invariants.
11523
+ * Validates that `pipeline.tasks` is an array.
11653
11524
  *
11654
- * @private internal step of `validatePipeline`
11525
+ * @private internal utility of `validatePipelineCollectionsStructure`
11655
11526
  */
11656
- function validatePipelineTasks({ pipeline, pipelineIdentification }) {
11657
- // Note: All input parameters are defined - so that they can be used as result of some task
11658
- const definedParameters = createInitiallyDefinedParameters(pipeline);
11659
- for (const task of pipeline.tasks) {
11660
- validatePipelineTask(task, definedParameters, pipelineIdentification);
11527
+ function validatePipelineTasksCollection(pipeline, pipelineIdentification) {
11528
+ // TODO: [🧠] Maybe do here some proper JSON-schema / ZOD checking
11529
+ if (Array.isArray(pipeline.tasks)) {
11530
+ return;
11661
11531
  }
11532
+ // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
11533
+ throw new ParseError(spaceTrim$1((block) => `
11534
+ Pipeline is valid JSON but with wrong structure
11535
+
11536
+ \`PipelineJson.tasks\` expected to be an array, but got ${typeof pipeline.tasks}
11537
+
11538
+ ${block(pipelineIdentification)}
11539
+ `));
11662
11540
  }
11541
+
11663
11542
  /**
11664
11543
  * Validates that task dependencies can be resolved without cycles or missing definitions.
11665
11544
  *
11666
- * @private internal step of `validatePipeline`
11545
+ * @private function of `validatePipeline`
11667
11546
  */
11668
- function validatePipelineDependencyResolution({ pipeline, pipelineIdentification }) {
11547
+ function validatePipelineDependencyResolution({ pipeline, pipelineIdentification, }) {
11669
11548
  let dependencyResolutionState = createInitialDependencyResolutionState(pipeline);
11670
11549
  let loopLimit = LOOP_LIMIT;
11671
11550
  while (hasUnresolvedTasks(dependencyResolutionState)) {
@@ -11676,29 +11555,211 @@ function validatePipelineDependencyResolution({ pipeline, pipelineIdentification
11676
11555
  }
11677
11556
  }
11678
11557
  /**
11679
- * Validates one pipeline parameter declaration.
11558
+ * Collects the parameter names that are already resolvable before dependency traversal starts.
11680
11559
  *
11681
- * @private internal step of `validatePipeline`
11560
+ * @private internal utility of `validatePipelineDependencyResolution`
11682
11561
  */
11683
- function validatePipelineParameter(parameter, pipeline, pipelineIdentification) {
11684
- validateParameterDirection(parameter, pipelineIdentification);
11685
- validateParameterUsage(parameter, pipeline, pipelineIdentification);
11686
- validateParameterDefinition(parameter, pipeline, pipelineIdentification);
11562
+ function createInitialDependencyResolutionState(pipeline) {
11563
+ return {
11564
+ resolvedParameterNames: createInitiallyResolvedParameterNames(pipeline),
11565
+ unresolvedTasks: [...pipeline.tasks],
11566
+ };
11687
11567
  }
11688
11568
  /**
11689
- * Validates one pipeline task and its invariants.
11569
+ * Checks whether dependency resolution still has tasks left to process.
11690
11570
  *
11691
- * @private internal step of `validatePipeline`
11571
+ * @private internal utility of `validatePipelineDependencyResolution`
11692
11572
  */
11693
- function validatePipelineTask(task, definedParameters, pipelineIdentification) {
11694
- validateTaskResultingParameter(task, definedParameters, pipelineIdentification);
11695
- validateTaskJokers(task, pipelineIdentification);
11696
- validateTaskExpectations(task, pipelineIdentification);
11573
+ function hasUnresolvedTasks({ unresolvedTasks }) {
11574
+ return unresolvedTasks.length > 0;
11575
+ }
11576
+ /**
11577
+ * Resolves the next batch of currently satisfiable tasks.
11578
+ *
11579
+ * @private internal utility of `validatePipelineDependencyResolution`
11580
+ */
11581
+ function resolveNextDependencyResolutionState(dependencyResolutionState, pipelineIdentification) {
11582
+ const currentlyResolvedTasks = getCurrentlyResolvedTasks(dependencyResolutionState.unresolvedTasks, dependencyResolutionState.resolvedParameterNames);
11583
+ if (currentlyResolvedTasks.length === 0) {
11584
+ throw createUnresolvedTasksError(dependencyResolutionState.unresolvedTasks, dependencyResolutionState.resolvedParameterNames, pipelineIdentification);
11585
+ }
11586
+ return {
11587
+ resolvedParameterNames: appendResolvedTaskParameterNames(dependencyResolutionState.resolvedParameterNames, currentlyResolvedTasks),
11588
+ unresolvedTasks: dependencyResolutionState.unresolvedTasks.filter((task) => !currentlyResolvedTasks.includes(task)),
11589
+ };
11590
+ }
11591
+ /**
11592
+ * Collects the parameter names that are already resolvable before dependency traversal starts.
11593
+ *
11594
+ * @private internal utility of `validatePipelineDependencyResolution`
11595
+ */
11596
+ function createInitiallyResolvedParameterNames(pipeline) {
11597
+ let resolvedParameterNames = pipeline.parameters
11598
+ .filter(({ isInput }) => isInput)
11599
+ .map(({ name }) => name);
11600
+ for (const reservedParameterName of RESERVED_PARAMETER_NAMES) {
11601
+ resolvedParameterNames = [...resolvedParameterNames, reservedParameterName];
11602
+ }
11603
+ return resolvedParameterNames;
11604
+ }
11605
+ /**
11606
+ * Adds newly resolved task outputs to the resolved parameter list.
11607
+ *
11608
+ * @private internal utility of `validatePipelineDependencyResolution`
11609
+ */
11610
+ function appendResolvedTaskParameterNames(resolvedParameterNames, currentlyResolvedTasks) {
11611
+ return [
11612
+ ...resolvedParameterNames,
11613
+ ...currentlyResolvedTasks.map(({ resultingParameterName }) => resultingParameterName),
11614
+ ];
11615
+ }
11616
+ /**
11617
+ * Selects tasks whose dependencies are already resolved.
11618
+ *
11619
+ * @private internal utility of `validatePipelineDependencyResolution`
11620
+ */
11621
+ function getCurrentlyResolvedTasks(unresolvedTasks, resolvedParameterNames) {
11622
+ return unresolvedTasks.filter((task) => task.dependentParameterNames.every((name) => resolvedParameterNames.includes(name)));
11623
+ }
11624
+ /**
11625
+ * Creates the unexpected loop-limit error for dependency resolution.
11626
+ *
11627
+ * @private internal utility of `validatePipelineDependencyResolution`
11628
+ */
11629
+ function createDependencyResolutionLoopLimitError(pipelineIdentification) {
11630
+ // Note: Really UnexpectedError not LimitReachedError - this should not happen and be caught below
11631
+ return new UnexpectedError(spaceTrim$1((block) => `
11632
+ Loop limit reached during detection of circular dependencies in \`validatePipeline\`
11633
+
11634
+ ${block(pipelineIdentification)}
11635
+ `));
11636
+ }
11637
+ /**
11638
+ * Creates the detailed error for unresolved or circular task dependencies.
11639
+ *
11640
+ * @private internal utility of `validatePipelineDependencyResolution`
11641
+ */
11642
+ function createUnresolvedTasksError(unresolvedTasks, resolvedParameterNames, pipelineIdentification) {
11643
+ return new PipelineLogicError(
11644
+ // TODO: [🐎] DRY
11645
+ spaceTrim$1((block) => `
11646
+
11647
+ Can not resolve some parameters:
11648
+ Either you are using a parameter that is not defined, or there are some circular dependencies.
11649
+
11650
+ ${block(pipelineIdentification)}
11651
+
11652
+ **Can not resolve:**
11653
+ ${block(unresolvedTasks
11654
+ .map(({ resultingParameterName, dependentParameterNames }) => `- Parameter \`{${resultingParameterName}}\` which depends on ${dependentParameterNames
11655
+ .map((dependentParameterName) => `\`{${dependentParameterName}}\``)
11656
+ .join(' and ')}`)
11657
+ .join('\n'))}
11658
+
11659
+ **Resolved:**
11660
+ ${block(resolvedParameterNames
11661
+ .filter((name) => !RESERVED_PARAMETER_NAMES.includes(name))
11662
+ .map((name) => `- Parameter \`{${name}}\``)
11663
+ .join('\n'))}
11664
+
11665
+
11666
+ **Reserved (which are available):**
11667
+ ${block(resolvedParameterNames
11668
+ .filter((name) => RESERVED_PARAMETER_NAMES.includes(name))
11669
+ .map((name) => `- Parameter \`{${name}}\``)
11670
+ .join('\n'))}
11671
+
11672
+
11673
+ `));
11674
+ }
11675
+
11676
+ /**
11677
+ * Tests if given string is valid semantic version
11678
+ *
11679
+ * Note: There are two similar functions:
11680
+ * - `isValidSemanticVersion` which tests any semantic version
11681
+ * - `isValidPromptbookVersion` *(this one)* which tests just Promptbook versions
11682
+ *
11683
+ * @public exported from `@promptbook/utils`
11684
+ */
11685
+ function isValidSemanticVersion(version) {
11686
+ if (typeof version !== 'string') {
11687
+ return false;
11688
+ }
11689
+ if (version.startsWith('0.0.0')) {
11690
+ return false;
11691
+ }
11692
+ return /^\d+\.\d+\.\d+(-\d+)?$/i.test(version);
11693
+ }
11694
+
11695
+ /**
11696
+ * Tests if given string is valid promptbook version
11697
+ * It looks into list of known promptbook versions.
11698
+ *
11699
+ * Note: When you are using for example promptbook 2.0.0 and there already is promptbook 3.0.0 it don`t know about it.
11700
+ * Note: There are two similar functions:
11701
+ * - `isValidSemanticVersion` which tests any semantic version
11702
+ * - `isValidPromptbookVersion` *(this one)* which tests just Promptbook versions
11703
+ *
11704
+ * @see https://www.npmjs.com/package/promptbook?activeTab=versions
11705
+ *
11706
+ * @public exported from `@promptbook/utils`
11707
+ */
11708
+ function isValidPromptbookVersion(version) {
11709
+ if (!isValidSemanticVersion(version)) {
11710
+ return false;
11711
+ }
11712
+ if ( /* version === '1.0.0' || */version === '2.0.0' || version === '3.0.0') {
11713
+ return false;
11714
+ }
11715
+ // <- TODO: [main] !!3 Check isValidPromptbookVersion against PROMPTBOOK_ENGINE_VERSIONS
11716
+ return true;
11717
+ }
11718
+
11719
+ /**
11720
+ * Tests if given string is valid pipeline URL URL.
11721
+ *
11722
+ * Note: There are few similar functions:
11723
+ * - `isValidUrl` which tests any URL
11724
+ * - `isValidAgentUrl` which tests just agent URL
11725
+ * - `isValidPipelineUrl` *(this one)* which tests just pipeline URL
11726
+ *
11727
+ * @public exported from `@promptbook/utils`
11728
+ */
11729
+ function isValidPipelineUrl(url) {
11730
+ if (!isValidUrl(url)) {
11731
+ return false;
11732
+ }
11733
+ if (!url.startsWith('https://') && !url.startsWith('http://') /* <- Note: [👣] */) {
11734
+ return false;
11735
+ }
11736
+ if (url.includes('#')) {
11737
+ // TODO: [🐠]
11738
+ return false;
11739
+ }
11740
+ /*
11741
+ Note: [👣][🧠] Is it secure to allow pipeline URLs on private and unsecured networks?
11742
+ if (isUrlOnPrivateNetwork(url)) {
11743
+ return false;
11744
+ }
11745
+ */
11746
+ return true;
11747
+ }
11748
+ // TODO: [🐠] Maybe more info why the URL is invalid
11749
+
11750
+ /**
11751
+ * Validates pipeline-level metadata fields.
11752
+ *
11753
+ * @private function of `validatePipeline`
11754
+ */
11755
+ function validatePipelineMetadata({ pipeline, pipelineIdentification }) {
11756
+ validatePipelineUrl(pipeline, pipelineIdentification);
11757
+ validatePipelineBookVersion(pipeline, pipelineIdentification);
11697
11758
  }
11698
11759
  /**
11699
11760
  * Validates the pipeline URL, when present.
11700
11761
  *
11701
- * @private internal utility of `validatePipeline`
11762
+ * @private internal utility of `validatePipelineMetadata`
11702
11763
  */
11703
11764
  function validatePipelineUrl(pipeline, pipelineIdentification) {
11704
11765
  if (pipeline.pipelineUrl === undefined || isValidPipelineUrl(pipeline.pipelineUrl)) {
@@ -11714,7 +11775,7 @@ function validatePipelineUrl(pipeline, pipelineIdentification) {
11714
11775
  /**
11715
11776
  * Validates the Promptbook version, when present.
11716
11777
  *
11717
- * @private internal utility of `validatePipeline`
11778
+ * @private internal utility of `validatePipelineMetadata`
11718
11779
  */
11719
11780
  function validatePipelineBookVersion(pipeline, pipelineIdentification) {
11720
11781
  if (pipeline.bookVersion === undefined || isValidPromptbookVersion(pipeline.bookVersion)) {
@@ -11727,48 +11788,31 @@ function validatePipelineBookVersion(pipeline, pipelineIdentification) {
11727
11788
  ${block(pipelineIdentification)}
11728
11789
  `));
11729
11790
  }
11791
+
11730
11792
  /**
11731
- * Validates that `pipeline.parameters` is an array.
11793
+ * Validates all pipeline parameter declarations.
11732
11794
  *
11733
- * @private internal utility of `validatePipeline`
11795
+ * @private function of `validatePipeline`
11734
11796
  */
11735
- function validatePipelineParametersCollection(pipeline, pipelineIdentification) {
11736
- // TODO: [🧠] Maybe do here some proper JSON-schema / ZOD checking
11737
- if (Array.isArray(pipeline.parameters)) {
11738
- return;
11797
+ function validatePipelineParameters({ pipeline, pipelineIdentification }) {
11798
+ for (const parameter of pipeline.parameters) {
11799
+ validatePipelineParameter(parameter, pipeline, pipelineIdentification);
11739
11800
  }
11740
- // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
11741
- throw new ParseError(spaceTrim$1((block) => `
11742
- Pipeline is valid JSON but with wrong structure
11743
-
11744
- \`PipelineJson.parameters\` expected to be an array, but got ${typeof pipeline.parameters}
11745
-
11746
- ${block(pipelineIdentification)}
11747
- `));
11748
11801
  }
11749
11802
  /**
11750
- * Validates that `pipeline.tasks` is an array.
11803
+ * Validates one pipeline parameter declaration.
11751
11804
  *
11752
- * @private internal utility of `validatePipeline`
11805
+ * @private internal utility of `validatePipelineParameters`
11753
11806
  */
11754
- function validatePipelineTasksCollection(pipeline, pipelineIdentification) {
11755
- // TODO: [🧠] Maybe do here some proper JSON-schema / ZOD checking
11756
- if (Array.isArray(pipeline.tasks)) {
11757
- return;
11758
- }
11759
- // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
11760
- throw new ParseError(spaceTrim$1((block) => `
11761
- Pipeline is valid JSON but with wrong structure
11762
-
11763
- \`PipelineJson.tasks\` expected to be an array, but got ${typeof pipeline.tasks}
11764
-
11765
- ${block(pipelineIdentification)}
11766
- `));
11807
+ function validatePipelineParameter(parameter, pipeline, pipelineIdentification) {
11808
+ validateParameterDirection(parameter, pipelineIdentification);
11809
+ validateParameterUsage(parameter, pipeline, pipelineIdentification);
11810
+ validateParameterDefinition(parameter, pipeline, pipelineIdentification);
11767
11811
  }
11768
11812
  /**
11769
11813
  * Validates that one parameter does not declare incompatible directions.
11770
11814
  *
11771
- * @private internal utility of `validatePipeline`
11815
+ * @private internal utility of `validatePipelineParameters`
11772
11816
  */
11773
11817
  function validateParameterDirection(parameter, pipelineIdentification) {
11774
11818
  if (!parameter.isInput || !parameter.isOutput) {
@@ -11785,7 +11829,7 @@ function validateParameterDirection(parameter, pipelineIdentification) {
11785
11829
  /**
11786
11830
  * Validates that one intermediate parameter is actually consumed by at least one task.
11787
11831
  *
11788
- * @private internal utility of `validatePipeline`
11832
+ * @private internal utility of `validatePipelineParameters`
11789
11833
  */
11790
11834
  function validateParameterUsage(parameter, pipeline, pipelineIdentification) {
11791
11835
  if (parameter.isInput || parameter.isOutput || isParameterUsedByAnyTask(parameter, pipeline.tasks)) {
@@ -11804,7 +11848,7 @@ function validateParameterUsage(parameter, pipeline, pipelineIdentification) {
11804
11848
  /**
11805
11849
  * Validates that one non-input parameter is produced by at least one task.
11806
11850
  *
11807
- * @private internal utility of `validatePipeline`
11851
+ * @private internal utility of `validatePipelineParameters`
11808
11852
  */
11809
11853
  function validateParameterDefinition(parameter, pipeline, pipelineIdentification) {
11810
11854
  if (parameter.isInput || isParameterDefinedByAnyTask(parameter, pipeline.tasks)) {
@@ -11823,7 +11867,7 @@ function validateParameterDefinition(parameter, pipeline, pipelineIdentification
11823
11867
  /**
11824
11868
  * Checks whether one parameter is consumed by at least one task dependency list.
11825
11869
  *
11826
- * @private internal utility of `validatePipeline`
11870
+ * @private internal utility of `validatePipelineParameters`
11827
11871
  */
11828
11872
  function isParameterUsedByAnyTask(parameter, tasks) {
11829
11873
  return tasks.some((task) => task.dependentParameterNames.includes(parameter.name));
@@ -11831,23 +11875,46 @@ function isParameterUsedByAnyTask(parameter, tasks) {
11831
11875
  /**
11832
11876
  * Checks whether one parameter is produced by at least one task.
11833
11877
  *
11834
- * @private internal utility of `validatePipeline`
11878
+ * @private internal utility of `validatePipelineParameters`
11835
11879
  */
11836
11880
  function isParameterDefinedByAnyTask(parameter, tasks) {
11837
11881
  return tasks.some((task) => task.resultingParameterName === parameter.name);
11838
11882
  }
11883
+
11884
+ /**
11885
+ * Validates all pipeline tasks and their per-task invariants.
11886
+ *
11887
+ * @private function of `validatePipeline`
11888
+ */
11889
+ function validatePipelineTasks({ pipeline, pipelineIdentification }) {
11890
+ // Note: All input parameters are defined - so that they can be used as result of some task
11891
+ const definedParameters = createInitiallyDefinedParameters(pipeline);
11892
+ for (const task of pipeline.tasks) {
11893
+ validatePipelineTask(task, definedParameters, pipelineIdentification);
11894
+ }
11895
+ }
11839
11896
  /**
11840
11897
  * Collects the parameter names that are already defined before task validation starts.
11841
11898
  *
11842
- * @private internal utility of `validatePipeline`
11899
+ * @private internal utility of `validatePipelineTasks`
11843
11900
  */
11844
11901
  function createInitiallyDefinedParameters(pipeline) {
11845
11902
  return new Set(pipeline.parameters.filter(({ isInput }) => isInput).map(({ name }) => name));
11846
11903
  }
11904
+ /**
11905
+ * Validates one pipeline task and its invariants.
11906
+ *
11907
+ * @private internal utility of `validatePipelineTasks`
11908
+ */
11909
+ function validatePipelineTask(task, definedParameters, pipelineIdentification) {
11910
+ validateTaskResultingParameter(task, definedParameters, pipelineIdentification);
11911
+ validateTaskJokers(task, pipelineIdentification);
11912
+ validateTaskExpectations(task, pipelineIdentification);
11913
+ }
11847
11914
  /**
11848
11915
  * Validates one task result parameter declaration and marks it as defined.
11849
11916
  *
11850
- * @private internal utility of `validatePipeline`
11917
+ * @private internal utility of `validatePipelineTasks`
11851
11918
  */
11852
11919
  function validateTaskResultingParameter(task, definedParameters, pipelineIdentification) {
11853
11920
  if (definedParameters.has(task.resultingParameterName)) {
@@ -11869,7 +11936,7 @@ function validateTaskResultingParameter(task, definedParameters, pipelineIdentif
11869
11936
  /**
11870
11937
  * Validates joker parameters for one task.
11871
11938
  *
11872
- * @private internal utility of `validatePipeline`
11939
+ * @private internal utility of `validatePipelineTasks`
11873
11940
  */
11874
11941
  function validateTaskJokers(task, pipelineIdentification) {
11875
11942
  if (!hasTaskJokers(task)) {
@@ -11881,7 +11948,7 @@ function validateTaskJokers(task, pipelineIdentification) {
11881
11948
  /**
11882
11949
  * Checks whether one task declares any joker parameters.
11883
11950
  *
11884
- * @private internal utility of `validatePipeline`
11951
+ * @private internal utility of `validatePipelineTasks`
11885
11952
  */
11886
11953
  function hasTaskJokers(task) {
11887
11954
  return !!task.jokerParameterNames && task.jokerParameterNames.length > 0;
@@ -11889,7 +11956,7 @@ function hasTaskJokers(task) {
11889
11956
  /**
11890
11957
  * Validates that a task has the required supporting features when using jokers.
11891
11958
  *
11892
- * @private internal utility of `validatePipeline`
11959
+ * @private internal utility of `validatePipelineTasks`
11893
11960
  */
11894
11961
  function validateTaskSupportsJokers(task, pipelineIdentification) {
11895
11962
  if (task.format || task.expectations /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
@@ -11904,7 +11971,7 @@ function validateTaskSupportsJokers(task, pipelineIdentification) {
11904
11971
  /**
11905
11972
  * Validates that every joker parameter is also listed among task dependencies.
11906
11973
  *
11907
- * @private internal utility of `validatePipeline`
11974
+ * @private internal utility of `validatePipelineTasks`
11908
11975
  */
11909
11976
  function validateTaskJokerDependencies(task, pipelineIdentification) {
11910
11977
  for (const joker of task.jokerParameterNames) {
@@ -11921,7 +11988,7 @@ function validateTaskJokerDependencies(task, pipelineIdentification) {
11921
11988
  /**
11922
11989
  * Validates all expectation bounds configured on one task.
11923
11990
  *
11924
- * @private internal utility of `validatePipeline`
11991
+ * @private internal utility of `validatePipelineTasks`
11925
11992
  */
11926
11993
  function validateTaskExpectations(task, pipelineIdentification) {
11927
11994
  if (!task.expectations) {
@@ -11936,7 +12003,7 @@ function validateTaskExpectations(task, pipelineIdentification) {
11936
12003
  /**
11937
12004
  * Validates the minimum and maximum expectation ordering for one unit.
11938
12005
  *
11939
- * @private internal utility of `validatePipeline`
12006
+ * @private internal utility of `validatePipelineTasks`
11940
12007
  */
11941
12008
  function validateTaskExpectationRange(unit, min, max, pipelineIdentification) {
11942
12009
  if (min === undefined || max === undefined || min <= max) {
@@ -11951,7 +12018,7 @@ function validateTaskExpectationRange(unit, min, max, pipelineIdentification) {
11951
12018
  /**
11952
12019
  * Validates the minimum expectation bound for one unit.
11953
12020
  *
11954
- * @private internal utility of `validatePipeline`
12021
+ * @private internal utility of `validatePipelineTasks`
11955
12022
  */
11956
12023
  function validateTaskExpectationMin(unit, min, pipelineIdentification) {
11957
12024
  if (min === undefined || min >= 0) {
@@ -11966,7 +12033,7 @@ function validateTaskExpectationMin(unit, min, pipelineIdentification) {
11966
12033
  /**
11967
12034
  * Validates the maximum expectation bound for one unit.
11968
12035
  *
11969
- * @private internal utility of `validatePipeline`
12036
+ * @private internal utility of `validatePipelineTasks`
11970
12037
  */
11971
12038
  function validateTaskExpectationMax(unit, max, pipelineIdentification) {
11972
12039
  if (max === undefined || max > 0) {
@@ -11978,123 +12045,62 @@ function validateTaskExpectationMax(unit, max, pipelineIdentification) {
11978
12045
  ${block(pipelineIdentification)}
11979
12046
  `));
11980
12047
  }
12048
+
11981
12049
  /**
11982
- * Collects the parameter names that are already resolvable before dependency traversal starts.
11983
- *
11984
- * @private internal utility of `validatePipeline`
11985
- */
11986
- function createInitialDependencyResolutionState(pipeline) {
11987
- return {
11988
- resolvedParameterNames: createInitiallyResolvedParameterNames(pipeline),
11989
- unresolvedTasks: [...pipeline.tasks],
11990
- };
11991
- }
11992
- /**
11993
- * Checks whether dependency resolution still has tasks left to process.
11994
- *
11995
- * @private internal utility of `validatePipeline`
11996
- */
11997
- function hasUnresolvedTasks({ unresolvedTasks }) {
11998
- return unresolvedTasks.length > 0;
11999
- }
12000
- /**
12001
- * Resolves the next batch of currently satisfiable tasks.
12050
+ * Validates PipelineJson if it is logically valid
12002
12051
  *
12003
- * @private internal utility of `validatePipeline`
12004
- */
12005
- function resolveNextDependencyResolutionState(dependencyResolutionState, pipelineIdentification) {
12006
- const currentlyResolvedTasks = getCurrentlyResolvedTasks(dependencyResolutionState.unresolvedTasks, dependencyResolutionState.resolvedParameterNames);
12007
- if (currentlyResolvedTasks.length === 0) {
12008
- throw createUnresolvedTasksError(dependencyResolutionState.unresolvedTasks, dependencyResolutionState.resolvedParameterNames, pipelineIdentification);
12009
- }
12010
- return {
12011
- resolvedParameterNames: appendResolvedTaskParameterNames(dependencyResolutionState.resolvedParameterNames, currentlyResolvedTasks),
12012
- unresolvedTasks: dependencyResolutionState.unresolvedTasks.filter((task) => !currentlyResolvedTasks.includes(task)),
12013
- };
12014
- }
12015
- /**
12016
- * Collects the parameter names that are already resolvable before dependency traversal starts.
12052
+ * It checks:
12053
+ * - if it has correct parameters dependency
12017
12054
  *
12018
- * @private internal utility of `validatePipeline`
12019
- */
12020
- function createInitiallyResolvedParameterNames(pipeline) {
12021
- let resolvedParameterNames = pipeline.parameters
12022
- .filter(({ isInput }) => isInput)
12023
- .map(({ name }) => name);
12024
- for (const reservedParameterName of RESERVED_PARAMETER_NAMES) {
12025
- resolvedParameterNames = [...resolvedParameterNames, reservedParameterName];
12026
- }
12027
- return resolvedParameterNames;
12028
- }
12029
- /**
12030
- * Adds newly resolved task outputs to the resolved parameter list.
12055
+ * It does NOT check:
12056
+ * - if it is valid json
12057
+ * - if it is meaningful
12031
12058
  *
12032
- * @private internal utility of `validatePipeline`
12033
- */
12034
- function appendResolvedTaskParameterNames(resolvedParameterNames, currentlyResolvedTasks) {
12035
- return [
12036
- ...resolvedParameterNames,
12037
- ...currentlyResolvedTasks.map(({ resultingParameterName }) => resultingParameterName),
12038
- ];
12039
- }
12040
- /**
12041
- * Selects tasks whose dependencies are already resolved.
12059
+ * Note: [🔂] This function is idempotent.
12042
12060
  *
12043
- * @private internal utility of `validatePipeline`
12044
- */
12045
- function getCurrentlyResolvedTasks(unresolvedTasks, resolvedParameterNames) {
12046
- return unresolvedTasks.filter((task) => task.dependentParameterNames.every((name) => resolvedParameterNames.includes(name)));
12047
- }
12048
- /**
12049
- * Creates the unexpected loop-limit error for dependency resolution.
12061
+ * @param pipeline valid or invalid PipelineJson
12062
+ * @returns the same pipeline if it is logically valid
12063
+ * @throws {PipelineLogicError} on logical error in the pipeline
12050
12064
  *
12051
- * @private internal utility of `validatePipeline`
12065
+ * @public exported from `@promptbook/core`
12052
12066
  */
12053
- function createDependencyResolutionLoopLimitError(pipelineIdentification) {
12054
- // Note: Really UnexpectedError not LimitReachedError - this should not happen and be caught below
12055
- return new UnexpectedError(spaceTrim$1((block) => `
12056
- Loop limit reached during detection of circular dependencies in \`validatePipeline\`
12067
+ function validatePipeline(pipeline) {
12068
+ if (IS_PIPELINE_LOGIC_VALIDATED) {
12069
+ validatePipeline_InnerFunction(pipeline);
12070
+ }
12071
+ else {
12072
+ try {
12073
+ validatePipeline_InnerFunction(pipeline);
12074
+ }
12075
+ catch (error) {
12076
+ if (!(error instanceof PipelineLogicError)) {
12077
+ throw error;
12078
+ }
12079
+ console.error(spaceTrim$1((block) => `
12080
+ Pipeline is not valid but logic errors are temporarily disabled via \`IS_PIPELINE_LOGIC_VALIDATED\`
12057
12081
 
12058
- ${block(pipelineIdentification)}
12059
- `));
12082
+ ${block(error.message)}
12083
+ `));
12084
+ }
12085
+ }
12086
+ return pipeline;
12060
12087
  }
12061
12088
  /**
12062
- * Creates the detailed error for unresolved or circular task dependencies.
12089
+ * Validates pipeline inner function.
12063
12090
  *
12064
- * @private internal utility of `validatePipeline`
12091
+ * @private internal function for `validatePipeline`
12065
12092
  */
12066
- function createUnresolvedTasksError(unresolvedTasks, resolvedParameterNames, pipelineIdentification) {
12067
- return new PipelineLogicError(
12068
- // TODO: [🐎] DRY
12069
- spaceTrim$1((block) => `
12070
-
12071
- Can not resolve some parameters:
12072
- Either you are using a parameter that is not defined, or there are some circular dependencies.
12073
-
12074
- ${block(pipelineIdentification)}
12075
-
12076
- **Can not resolve:**
12077
- ${block(unresolvedTasks
12078
- .map(({ resultingParameterName, dependentParameterNames }) => `- Parameter \`{${resultingParameterName}}\` which depends on ${dependentParameterNames
12079
- .map((dependentParameterName) => `\`{${dependentParameterName}}\``)
12080
- .join(' and ')}`)
12081
- .join('\n'))}
12082
-
12083
- **Resolved:**
12084
- ${block(resolvedParameterNames
12085
- .filter((name) => !RESERVED_PARAMETER_NAMES.includes(name))
12086
- .map((name) => `- Parameter \`{${name}}\``)
12087
- .join('\n'))}
12088
-
12089
-
12090
- **Reserved (which are available):**
12091
- ${block(resolvedParameterNames
12092
- .filter((name) => RESERVED_PARAMETER_NAMES.includes(name))
12093
- .map((name) => `- Parameter \`{${name}}\``)
12094
- .join('\n'))}
12095
-
12096
-
12097
- `));
12093
+ function validatePipeline_InnerFunction(pipeline) {
12094
+ // TODO: [🧠] Maybe test if promptbook is a promise and make specific error case for that
12095
+ const context = createPipelineValidationContext(pipeline);
12096
+ validatePipelineMetadata(context);
12097
+ validatePipelineCollectionsStructure(context);
12098
+ validatePipelineParameters(context);
12099
+ validatePipelineTasks(context);
12100
+ validatePipelineDependencyResolution(context);
12101
+ // Note: Check that formfactor is corresponding to the pipeline interface
12102
+ // TODO: !!6 Implement this
12103
+ // pipeline.formfactorName
12098
12104
  }
12099
12105
  /**
12100
12106
  * TODO: [🧞‍♀️] Do not allow joker + foreach
@@ -20752,7 +20758,7 @@ class MessageSuffixCommitmentDefinition extends BaseCommitmentDefinition {
20752
20758
  * META commitment definition
20753
20759
  *
20754
20760
  * The META commitment handles all meta-information about the agent such as:
20755
- * - META AVATAR: Sets the agent's built-in default avatar visual
20761
+ * - META AVATAR / META VISUAL: Sets the agent's built-in default avatar visual
20756
20762
  * - META IMAGE: Sets the agent's avatar/profile image URL
20757
20763
  * - META LINK: Provides profile/source links for the person the agent models
20758
20764
  * - META DOMAIN: Sets the canonical custom domain/host of the agent
@@ -20767,7 +20773,7 @@ class MessageSuffixCommitmentDefinition extends BaseCommitmentDefinition {
20767
20773
  * Example usage in agent source:
20768
20774
  *
20769
20775
  * ```book
20770
- * META AVATAR pixel-art
20776
+ * META VISUAL pixel-art
20771
20777
  * META IMAGE https://example.com/avatar.jpg
20772
20778
  * META LINK https://twitter.com/username
20773
20779
  * META DOMAIN my-agent.com
@@ -20807,7 +20813,7 @@ class MetaCommitmentDefinition extends BaseCommitmentDefinition {
20807
20813
 
20808
20814
  ## Supported META types
20809
20815
 
20810
- - **META AVATAR** - Sets the agent's built-in default avatar visual
20816
+ - **META AVATAR** / **META VISUAL** - Sets the agent's built-in default avatar visual
20811
20817
  - **META IMAGE** - Sets the agent's avatar/profile image URL
20812
20818
  - **META LINK** - Provides profile/source links for the person the agent models
20813
20819
  - **META DOMAIN** - Sets the canonical custom domain/host of the agent
@@ -20831,7 +20837,7 @@ class MetaCommitmentDefinition extends BaseCommitmentDefinition {
20831
20837
  \`\`\`book
20832
20838
  Professional Assistant
20833
20839
 
20834
- META AVATAR octopus3
20840
+ META VISUAL octopus3
20835
20841
  META IMAGE https://example.com/professional-avatar.jpg
20836
20842
  META TITLE Senior Business Consultant
20837
20843
  META DESCRIPTION Specialized in strategic planning and project management
@@ -24002,452 +24008,13 @@ function formatAlphaHex$1(opacity) {
24002
24008
  .padStart(2, '0');
24003
24009
  }
24004
24010
 
24005
- /* eslint-disable no-magic-numbers */
24006
- /**
24007
- * Light direction used by the organic 3D octopus shading.
24008
- *
24009
- * @private helper of `octopus3dAvatarVisual`
24010
- */
24011
- const LIGHT_DIRECTION$3 = normalizeVector3({
24012
- x: 0.48,
24013
- y: -0.62,
24014
- z: 0.94,
24015
- });
24016
- /**
24017
- * Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
24018
- *
24019
- * @private helper of `octopus3dAvatarVisual`
24020
- */
24021
- const octopus3dStableStateCache = new WeakMap();
24022
- /**
24023
- * Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
24024
- *
24025
- * @private helper of `octopus3dAvatarVisual`
24026
- */
24027
- function getOctopus3dStableState(createRandom) {
24028
- const cached = octopus3dStableStateCache.get(createRandom);
24029
- if (cached !== undefined) {
24030
- return cached;
24031
- }
24032
- const animationRandom = createRandom('octopus3d-animation-profile');
24033
- const eyeRandom = createRandom('octopus3d-eye-profile');
24034
- const leftEyePhaseOffset = eyeRandom() * 0.6;
24035
- const rightEyePhaseOffset = eyeRandom() * 0.6;
24036
- const state = {
24037
- morphologyProfile: createOctopus3MorphologyProfile(createRandom),
24038
- animationPhase: animationRandom() * Math.PI * 2,
24039
- leftEyePhaseOffset,
24040
- rightEyePhaseOffset,
24041
- };
24042
- octopus3dStableStateCache.set(createRandom, state);
24043
- return state;
24044
- }
24045
- /**
24046
- * Proper 3D Octopus visual built from projected organic meshes and tentacles.
24047
- *
24048
- * @private built-in avatar visual
24049
- */
24050
- const octopus3dAvatarVisual = {
24051
- id: 'octopus3d',
24052
- title: 'Octopus 3D',
24053
- description: 'Proper 3D octopus portrait with a turning silhouette, expressive eyes, and depth-sorted tentacles.',
24054
- isAnimated: true,
24055
- supportsPointerTracking: true,
24056
- render({ context, size, palette, createRandom, timeMs, interaction }) {
24057
- const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3dStableState(createRandom);
24058
- const sceneCenterX = size * 0.5;
24059
- const sceneCenterY = size * 0.56;
24060
- const bob = Math.sin(timeMs / 920 + animationPhase) * size * 0.014;
24061
- const mantleCenter = {
24062
- x: interaction.bodyOffsetX * size * 0.042 + size * morphologyProfile.body.centerXJitterRatio * 0.65,
24063
- y: -size * 0.09 + interaction.bodyOffsetY * size * 0.028 + bob,
24064
- z: interaction.intensity * size * 0.012,
24065
- };
24066
- const underbodyCenter = {
24067
- x: mantleCenter.x * 0.86,
24068
- y: mantleCenter.y + size * 0.168,
24069
- z: mantleCenter.z - size * 0.018,
24070
- };
24071
- const mantleRadiusX = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.horizontalStretch;
24072
- const mantleRadiusY = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.verticalStretch * 1.1;
24073
- const mantleRadiusZ = size *
24074
- morphologyProfile.body.bodyRadiusRatio *
24075
- (0.9 + (morphologyProfile.body.horizontalStretch - 1) * 0.3);
24076
- const underbodyRadiusX = mantleRadiusX * (0.9 + (morphologyProfile.tentacles.rootSpreadScale - 1) * 0.08);
24077
- const underbodyRadiusY = mantleRadiusY * (0.44 + morphologyProfile.body.lowerDropRatio * 3.1);
24078
- const underbodyRadiusZ = mantleRadiusZ * 0.78;
24079
- const bodyYaw = -0.18 +
24080
- Math.sin(timeMs / 2400 + animationPhase) * 0.05 +
24081
- interaction.bodyOffsetX * 0.18 +
24082
- interaction.gazeX * 0.22;
24083
- const bodyPitch = -0.08 +
24084
- Math.cos(timeMs / 2700 + animationPhase * 0.6) * 0.025 -
24085
- interaction.bodyOffsetY * 0.08 -
24086
- interaction.gazeY * 0.08;
24087
- const headYaw = bodyYaw - 0.04 + interaction.gazeX * 0.56;
24088
- const headPitch = bodyPitch - 0.02 - interaction.gazeY * 0.32;
24089
- const mantlePatches = resolveVisibleEllipsoidPatches({
24090
- center: mantleCenter,
24091
- radiusX: mantleRadiusX,
24092
- radiusY: mantleRadiusY,
24093
- radiusZ: mantleRadiusZ,
24094
- rotationX: headPitch,
24095
- rotationY: headYaw,
24096
- sceneCenterX,
24097
- sceneCenterY,
24098
- size,
24099
- palette,
24100
- verticalColorBias: 0,
24101
- outlineColor: `${palette.highlight}7a`,
24102
- });
24103
- const underbodyPatches = resolveVisibleEllipsoidPatches({
24104
- center: underbodyCenter,
24105
- radiusX: underbodyRadiusX,
24106
- radiusY: underbodyRadiusY,
24107
- radiusZ: underbodyRadiusZ,
24108
- rotationX: bodyPitch,
24109
- rotationY: bodyYaw,
24110
- sceneCenterX,
24111
- sceneCenterY,
24112
- size,
24113
- palette,
24114
- verticalColorBias: 0.18,
24115
- outlineColor: `${palette.shadow}8f`,
24116
- });
24117
- const tentacleStrokes = createOctopusTentacleStrokes({
24118
- createRandom,
24119
- morphologyProfile,
24120
- timeMs,
24121
- size,
24122
- center: underbodyCenter,
24123
- radiusX: underbodyRadiusX,
24124
- radiusY: underbodyRadiusY,
24125
- radiusZ: underbodyRadiusZ,
24126
- rotationX: bodyPitch,
24127
- rotationY: bodyYaw,
24128
- sceneCenterX,
24129
- sceneCenterY,
24130
- animationPhase,
24131
- });
24132
- const faceEyeSpacing = size * morphologyProfile.face.eyeSpacingRatio * 0.92;
24133
- const faceEyeYOffset = size * morphologyProfile.face.eyeCenterYOffsetRatio - mantleRadiusY * 0.02;
24134
- const faceEyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio * 0.82;
24135
- const faceEyeRadiusY = faceEyeRadiusX * morphologyProfile.face.eyeHeightRatio * 0.96;
24136
- const mouthHalfWidth = size * morphologyProfile.face.mouthWidthRatio * 0.92;
24137
- const mouthY = size * morphologyProfile.face.mouthYOffsetRatio + mantleRadiusY * 0.08;
24138
- drawAvatarFrame(context, size, palette);
24139
- drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs);
24140
- drawOctopus3dShadow(context, size, palette, interaction, timeMs);
24141
- for (const tentacleStroke of tentacleStrokes.filter((candidateTentacleStroke) => !candidateTentacleStroke.isFrontFacing)) {
24142
- drawTentacleStroke(context, tentacleStroke, palette);
24143
- }
24144
- for (const surfacePatch of [...mantlePatches, ...underbodyPatches].sort((firstSurfacePatch, secondSurfacePatch) => firstSurfacePatch.averageDepth - secondSurfacePatch.averageDepth)) {
24145
- drawSurfacePatch(context, surfacePatch);
24146
- }
24147
- for (const tentacleStroke of tentacleStrokes.filter((candidateTentacleStroke) => candidateTentacleStroke.isFrontFacing)) {
24148
- drawTentacleStroke(context, tentacleStroke, palette);
24149
- }
24150
- drawProjectedOrganicEye(context, {
24151
- x: -faceEyeSpacing,
24152
- y: faceEyeYOffset,
24153
- z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -faceEyeSpacing, faceEyeYOffset),
24154
- }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
24155
- drawProjectedOrganicEye(context, {
24156
- x: faceEyeSpacing,
24157
- y: faceEyeYOffset,
24158
- z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
24159
- }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
24160
- drawProjectedOrganicMouth(context, [
24161
- {
24162
- x: -mouthHalfWidth,
24163
- y: mouthY,
24164
- z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -mouthHalfWidth, mouthY),
24165
- },
24166
- {
24167
- x: size * morphologyProfile.face.mouthCenterOffsetRatio,
24168
- y: mouthY +
24169
- size * morphologyProfile.face.mouthCurveDepthRatio * 0.38 +
24170
- Math.sin(timeMs / 760 + animationPhase) * size * 0.01 +
24171
- interaction.gazeY * size * 0.01,
24172
- z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, size * morphologyProfile.face.mouthCenterOffsetRatio, mouthY),
24173
- },
24174
- {
24175
- x: mouthHalfWidth,
24176
- y: mouthY,
24177
- z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, mouthHalfWidth, mouthY),
24178
- },
24179
- ], mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, palette, size);
24180
- },
24181
- };
24182
- /**
24183
- * Draws the atmospheric underwater glow behind the octopus mesh.
24184
- *
24185
- * @private helper of `octopus3dAvatarVisual`
24186
- */
24187
- function drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs) {
24188
- const glowGradient = context.createRadialGradient(sceneCenterX + interaction.gazeX * size * 0.1, sceneCenterY - size * 0.2 + interaction.gazeY * size * 0.05, size * 0.04, sceneCenterX, sceneCenterY - size * 0.04, size * 0.62);
24189
- glowGradient.addColorStop(0, `${palette.highlight}5c`);
24190
- glowGradient.addColorStop(0.36, `${palette.accent}24`);
24191
- glowGradient.addColorStop(1, `${palette.highlight}00`);
24192
- context.fillStyle = glowGradient;
24193
- context.fillRect(0, 0, size, size);
24194
- const lowerGradient = context.createRadialGradient(sceneCenterX + Math.sin(timeMs / 1700) * size * 0.05, sceneCenterY + size * 0.23, size * 0.08, sceneCenterX, sceneCenterY + size * 0.28, size * 0.5);
24195
- lowerGradient.addColorStop(0, `${palette.secondary}1d`);
24196
- lowerGradient.addColorStop(1, `${palette.secondary}00`);
24197
- context.fillStyle = lowerGradient;
24198
- context.fillRect(0, 0, size, size);
24199
- }
24200
- /**
24201
- * Draws the soft ground shadow below the octopus.
24202
- *
24203
- * Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
24204
- * blurry ellipse without triggering a costly software rasterization pass on every frame.
24205
- *
24206
- * @private helper of `octopus3dAvatarVisual`
24207
- */
24208
- function drawOctopus3dShadow(context, size, palette, interaction, timeMs) {
24209
- const cx = size * 0.5 + interaction.gazeX * size * 0.04;
24210
- const cy = size * 0.87 + Math.sin(timeMs / 920) * size * 0.008;
24211
- const rx = size * (0.18 + interaction.intensity * 0.02);
24212
- const ry = size * 0.06;
24213
- context.save();
24214
- context.translate(cx, cy);
24215
- context.scale(1, ry / rx);
24216
- const blurRadius = rx * 1.4;
24217
- const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
24218
- shadowGradient.addColorStop(0, `${palette.shadow}7a`);
24219
- shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
24220
- shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
24221
- shadowGradient.addColorStop(1, `${palette.shadow}00`);
24222
- context.fillStyle = shadowGradient;
24223
- context.beginPath();
24224
- context.arc(0, 0, blurRadius, 0, Math.PI * 2);
24225
- context.fill();
24226
- context.restore();
24227
- }
24228
- /**
24229
- * Resolves visible projected patches for one rotated ellipsoid mesh.
24230
- *
24231
- * @private helper of `octopus3dAvatarVisual`
24232
- */
24233
- function resolveVisibleEllipsoidPatches(options) {
24234
- const { center, radiusX, radiusY, radiusZ, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, verticalColorBias, outlineColor, } = options;
24235
- const latitudePatchCount = 10;
24236
- const longitudePatchCount = 18;
24237
- const surfacePatches = [];
24238
- for (let latitudeIndex = 0; latitudeIndex < latitudePatchCount; latitudeIndex++) {
24239
- const startLatitude = -Math.PI / 2 + (latitudeIndex / latitudePatchCount) * Math.PI;
24240
- const endLatitude = -Math.PI / 2 + ((latitudeIndex + 1) / latitudePatchCount) * Math.PI;
24241
- const verticalProgress = (latitudeIndex + 0.5) / latitudePatchCount;
24242
- for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
24243
- const startLongitude = -Math.PI + (longitudeIndex / longitudePatchCount) * Math.PI * 2;
24244
- const endLongitude = -Math.PI + ((longitudeIndex + 1) / longitudePatchCount) * Math.PI * 2;
24245
- const localCorners = [
24246
- sampleEllipsoidPoint(radiusX, radiusY, radiusZ, startLatitude, startLongitude),
24247
- sampleEllipsoidPoint(radiusX, radiusY, radiusZ, startLatitude, endLongitude),
24248
- sampleEllipsoidPoint(radiusX, radiusY, radiusZ, endLatitude, endLongitude),
24249
- sampleEllipsoidPoint(radiusX, radiusY, radiusZ, endLatitude, startLongitude),
24250
- ];
24251
- const transformedCorners = localCorners.map((localCorner) => transformScenePoint(localCorner, center, rotationX, rotationY));
24252
- const surfaceNormal = normalizeVector3(crossProduct3D(subtractPoint3D(transformedCorners[1], transformedCorners[0]), subtractPoint3D(transformedCorners[2], transformedCorners[0])));
24253
- if (surfaceNormal.z <= 0.01) {
24254
- continue;
24255
- }
24256
- const projectedCorners = transformedCorners.map((transformedCorner) => projectScenePoint(transformedCorner, size, sceneCenterX, sceneCenterY));
24257
- surfacePatches.push({
24258
- corners: projectedCorners,
24259
- averageDepth: transformedCorners.reduce((depthSum, transformedCorner) => depthSum + transformedCorner.z, 0) /
24260
- transformedCorners.length,
24261
- lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$3), -1, 1),
24262
- fillStyle: resolveSurfacePatchFillStyle(palette, verticalProgress + verticalColorBias),
24263
- outlineColor,
24264
- });
24265
- }
24266
- }
24267
- return surfacePatches;
24268
- }
24269
- /**
24270
- * Samples one point on an ellipsoid aligned to the local axes.
24271
- *
24272
- * @private helper of `octopus3dAvatarVisual`
24273
- */
24274
- function sampleEllipsoidPoint(radiusX, radiusY, radiusZ, latitude, longitude) {
24275
- const cosineLatitude = Math.cos(latitude);
24276
- return {
24277
- x: Math.sin(longitude) * cosineLatitude * radiusX,
24278
- y: Math.sin(latitude) * radiusY,
24279
- z: Math.cos(longitude) * cosineLatitude * radiusZ,
24280
- };
24281
- }
24282
- /**
24283
- * Resolves one base fill tone for a surface patch across the octopus body.
24284
- *
24285
- * @private helper of `octopus3dAvatarVisual`
24286
- */
24287
- function resolveSurfacePatchFillStyle(palette, verticalProgress) {
24288
- const clampedVerticalProgress = clampNumber$1(verticalProgress, 0, 1);
24289
- if (clampedVerticalProgress < 0.2) {
24290
- return palette.highlight;
24291
- }
24292
- if (clampedVerticalProgress < 0.45) {
24293
- return palette.secondary;
24294
- }
24295
- if (clampedVerticalProgress < 0.8) {
24296
- return palette.primary;
24297
- }
24298
- return `${palette.shadow}f2`;
24299
- }
24300
- /**
24301
- * Draws one projected mesh patch with organic shading.
24302
- *
24303
- * @private helper of `octopus3dAvatarVisual`
24304
- */
24305
- function drawSurfacePatch(context, surfacePatch) {
24306
- drawProjectedQuad(context, surfacePatch.corners, surfacePatch.fillStyle);
24307
- if (surfacePatch.lightIntensity > 0) {
24308
- drawProjectedQuad(context, surfacePatch.corners, `rgba(255, 255, 255, ${0.15 * surfacePatch.lightIntensity})`);
24309
- }
24310
- else if (surfacePatch.lightIntensity < 0) {
24311
- drawProjectedQuad(context, surfacePatch.corners, `rgba(0, 0, 0, ${0.24 * Math.abs(surfacePatch.lightIntensity)})`);
24312
- }
24313
- context.save();
24314
- context.beginPath();
24315
- context.moveTo(surfacePatch.corners[0].x, surfacePatch.corners[0].y);
24316
- for (let cornerIndex = 1; cornerIndex < surfacePatch.corners.length; cornerIndex++) {
24317
- context.lineTo(surfacePatch.corners[cornerIndex].x, surfacePatch.corners[cornerIndex].y);
24318
- }
24319
- context.closePath();
24320
- context.strokeStyle = surfacePatch.outlineColor;
24321
- context.lineWidth = Math.max(1, getProjectedQuadPerimeter(surfacePatch.corners) * 0.0044);
24322
- context.lineJoin = 'round';
24323
- context.stroke();
24324
- context.restore();
24325
- }
24326
- /**
24327
- * Creates the projected 3D tentacle strokes orbiting around the lower octopus body.
24328
- *
24329
- * @private helper of `octopus3dAvatarVisual`
24330
- */
24331
- function createOctopusTentacleStrokes(options) {
24332
- const { createRandom, morphologyProfile, timeMs, size, center, radiusX, radiusY, radiusZ, rotationX, rotationY, sceneCenterX, sceneCenterY, animationPhase, } = options;
24333
- return Array.from({ length: morphologyProfile.tentacles.count }, (_, tentacleIndex) => {
24334
- const tentacleRandom = createRandom(`octopus3d-tentacle-${tentacleIndex}`);
24335
- const spreadProgress = morphologyProfile.tentacles.count === 1 ? 0.5 : tentacleIndex / (morphologyProfile.tentacles.count - 1);
24336
- const orbitAngle = -Math.PI * 0.92 + spreadProgress * Math.PI * 1.84 + (tentacleRandom() - 0.5) * 0.16;
24337
- const flowLength = size * (0.19 + morphologyProfile.tentacles.flowLengthScale * 0.075 + tentacleRandom() * 0.018);
24338
- const lateralReach = size *
24339
- (0.08 + morphologyProfile.tentacles.lateralReachScale * 0.05 + Math.abs(Math.sin(orbitAngle)) * 0.018);
24340
- const depthReach = size * (0.028 + morphologyProfile.tentacles.tipReachScale * 0.032);
24341
- const sway = Math.sin(timeMs / (760 + tentacleIndex * 36) + animationPhase + tentacleRandom() * Math.PI * 2);
24342
- const anchorPoint = {
24343
- x: Math.sin(orbitAngle) * radiusX * (0.84 + tentacleRandom() * 0.08),
24344
- y: radiusY * (0.22 + tentacleRandom() * 0.18),
24345
- z: Math.cos(orbitAngle) * radiusZ * (0.72 + tentacleRandom() * 0.12),
24346
- };
24347
- const controlPointOne = {
24348
- x: anchorPoint.x + Math.sin(orbitAngle) * lateralReach * 0.44,
24349
- y: anchorPoint.y + flowLength * 0.26,
24350
- z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.3 + sway * size * 0.012,
24351
- };
24352
- const controlPointTwo = {
24353
- x: anchorPoint.x +
24354
- Math.sin(orbitAngle) * lateralReach * (0.82 + morphologyProfile.tentacles.swayScale * 0.12),
24355
- y: anchorPoint.y + flowLength * 0.66,
24356
- z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.72 + sway * size * 0.02,
24357
- };
24358
- const endPoint = {
24359
- x: anchorPoint.x +
24360
- Math.sin(orbitAngle) * lateralReach * (1.02 + morphologyProfile.tentacles.tipWidthScale * 0.12) +
24361
- sway * size * 0.028,
24362
- y: anchorPoint.y + flowLength,
24363
- z: anchorPoint.z + Math.cos(orbitAngle) * depthReach + sway * size * 0.016,
24364
- };
24365
- const scenePoints = Array.from({ length: 12 }, (_, sampleIndex) => transformScenePoint(sampleCubicBezierPoint3D(anchorPoint, controlPointOne, controlPointTwo, endPoint, sampleIndex / 11), center, rotationX, rotationY));
24366
- const projectedPoints = scenePoints.map((scenePoint) => projectScenePoint(scenePoint, size, sceneCenterX, sceneCenterY));
24367
- const averageDepth = scenePoints.reduce((depthSum, scenePoint) => depthSum + scenePoint.z, 0) / scenePoints.length;
24368
- return {
24369
- projectedPoints,
24370
- averageDepth,
24371
- isFrontFacing: averageDepth >= center.z - size * 0.006,
24372
- baseWidth: size *
24373
- (0.019 +
24374
- morphologyProfile.tentacles.baseWidthScale * 0.007 +
24375
- tentacleRandom() * 0.003 +
24376
- Math.abs(Math.sin(orbitAngle)) * 0.002),
24377
- tipWidth: size * (0.0046 + morphologyProfile.tentacles.tipWidthScale * 0.0018),
24378
- colorBias: tentacleRandom(),
24379
- };
24380
- });
24381
- }
24382
- /**
24383
- * Samples one point on a cubic Bezier curve in 3D.
24384
- *
24385
- * @private helper of `octopus3dAvatarVisual`
24386
- */
24387
- function sampleCubicBezierPoint3D(startPoint, controlPointOne, controlPointTwo, endPoint, progress) {
24388
- const inverseProgress = 1 - progress;
24389
- return {
24390
- x: inverseProgress * inverseProgress * inverseProgress * startPoint.x +
24391
- 3 * inverseProgress * inverseProgress * progress * controlPointOne.x +
24392
- 3 * inverseProgress * progress * progress * controlPointTwo.x +
24393
- progress * progress * progress * endPoint.x,
24394
- y: inverseProgress * inverseProgress * inverseProgress * startPoint.y +
24395
- 3 * inverseProgress * inverseProgress * progress * controlPointOne.y +
24396
- 3 * inverseProgress * progress * progress * controlPointTwo.y +
24397
- progress * progress * progress * endPoint.y,
24398
- z: inverseProgress * inverseProgress * inverseProgress * startPoint.z +
24399
- 3 * inverseProgress * inverseProgress * progress * controlPointOne.z +
24400
- 3 * inverseProgress * progress * progress * controlPointTwo.z +
24401
- progress * progress * progress * endPoint.z,
24402
- };
24403
- }
24404
- /**
24405
- * Draws one projected tentacle stroke with a slim highlight ridge.
24406
- *
24407
- * @private helper of `octopus3dAvatarVisual`
24408
- */
24409
- function drawTentacleStroke(context, tentacleStroke, palette) {
24410
- const projectedSegments = tentacleStroke.projectedPoints.length - 1;
24411
- for (let segmentIndex = 0; segmentIndex < projectedSegments; segmentIndex++) {
24412
- const startPoint = tentacleStroke.projectedPoints[segmentIndex];
24413
- const endPoint = tentacleStroke.projectedPoints[segmentIndex + 1];
24414
- const progress = segmentIndex / projectedSegments;
24415
- const width = tentacleStroke.baseWidth + (tentacleStroke.tipWidth - tentacleStroke.baseWidth) * progress;
24416
- context.beginPath();
24417
- context.moveTo(startPoint.x, startPoint.y);
24418
- context.lineTo(endPoint.x, endPoint.y);
24419
- context.strokeStyle = tentacleStroke.colorBias > 0.6 ? `${palette.secondary}f0` : `${palette.primary}f0`;
24420
- context.lineWidth = width;
24421
- context.lineCap = 'round';
24422
- context.stroke();
24423
- context.beginPath();
24424
- context.moveTo(startPoint.x, startPoint.y);
24425
- context.lineTo(endPoint.x, endPoint.y);
24426
- context.strokeStyle = tentacleStroke.isFrontFacing ? `${palette.highlight}80` : `${palette.highlight}40`;
24427
- context.lineWidth = Math.max(1, width * 0.34);
24428
- context.lineCap = 'round';
24429
- context.stroke();
24430
- }
24431
- }
24432
- /**
24433
- * Resolves the front surface depth on an ellipsoid for one local face point.
24434
- *
24435
- * @private helper of `octopus3dAvatarVisual`
24436
- */
24437
- function resolveEllipsoidSurfaceDepth(radiusX, radiusY, radiusZ, x, y) {
24438
- const normalizedX = x / radiusX;
24439
- const normalizedY = y / radiusY;
24440
- const remainingDepthRatio = Math.max(0, 1 - normalizedX * normalizedX - normalizedY * normalizedY);
24441
- return Math.sqrt(remainingDepthRatio) * radiusZ;
24442
- }
24443
-
24444
24011
  /* eslint-disable no-magic-numbers */
24445
24012
  /**
24446
24013
  * Light direction used by the single-mesh octopus shading.
24447
24014
  *
24448
24015
  * @private helper of `octopus3d2AvatarVisual`
24449
24016
  */
24450
- const LIGHT_DIRECTION$2 = normalizeVector3({
24017
+ const LIGHT_DIRECTION$3 = normalizeVector3({
24451
24018
  x: 0.38,
24452
24019
  y: -0.6,
24453
24020
  z: 0.98,
@@ -24686,7 +24253,7 @@ function resolveVisibleBlobbyOctopusPatches(options) {
24686
24253
  transformedCorners[2].z +
24687
24254
  transformedCorners[3].z) /
24688
24255
  4,
24689
- lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$2), -1, 1),
24256
+ lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$3), -1, 1),
24690
24257
  fillStyle: resolveBlobbySurfacePatchFillStyle$1(palette, verticalProgress, Math.max(0, Math.cos(centerLongitude)), resolveLowerLobeWave(centerLongitude, morphologyProfile, animationPhase, timeMs)),
24691
24258
  outlineColor: verticalProgress < 0.58 ? `${palette.highlight}73` : `${palette.shadow}8a`,
24692
24259
  });
@@ -24801,7 +24368,7 @@ function drawBlobbySurfacePatch(context, surfacePatch) {
24801
24368
  *
24802
24369
  * @private helper of `octopus3d3AvatarVisual`
24803
24370
  */
24804
- const LIGHT_DIRECTION$1 = normalizeVector3({
24371
+ const LIGHT_DIRECTION$2 = normalizeVector3({
24805
24372
  x: 0.34,
24806
24373
  y: -0.62,
24807
24374
  z: 1,
@@ -25108,7 +24675,7 @@ function resolveVisibleContinuousOctopusPatches(options) {
25108
24675
  transformedCorners[2].z +
25109
24676
  transformedCorners[3].z) /
25110
24677
  4,
25111
- lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$1), -1, 1),
24678
+ lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$2), -1, 1),
25112
24679
  fillStyle: resolveContinuousSurfacePatchFillStyle(palette, verticalProgress, cachedCosByPatchCenterLongitude[longitudeIndex], cachedTentacleInfluencesByPatchCenterLongitude[longitudeIndex].core, cachedLobeWavesByPatchCenterLongitude[longitudeIndex]),
25113
24680
  outlineColor: verticalProgress < 0.54 ? `${palette.highlight}69` : `${palette.shadow}78`,
25114
24681
  });
@@ -25423,7 +24990,7 @@ function smoothStep$1(edgeStart, edgeEnd, value) {
25423
24990
  *
25424
24991
  * @private helper of `octopus3d4AvatarVisual`
25425
24992
  */
25426
- const LIGHT_DIRECTION = normalizeVector3({
24993
+ const LIGHT_DIRECTION$1 = normalizeVector3({
25427
24994
  x: 0.32,
25428
24995
  y: -0.66,
25429
24996
  z: 1,
@@ -25494,7 +25061,7 @@ const octopus3d4AvatarVisual = {
25494
25061
  isAnimated: true,
25495
25062
  supportsPointerTracking: true,
25496
25063
  render({ context, size, palette, createRandom, timeMs, interaction }) {
25497
- const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset, tentacleProfiles, skinSpots } = getOctopus3d4StableState(createRandom);
25064
+ const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset, tentacleProfiles, skinSpots, } = getOctopus3d4StableState(createRandom);
25498
25065
  const sceneCenterX = size * 0.5;
25499
25066
  const sceneCenterY = size * 0.535;
25500
25067
  const bob = Math.sin(timeMs / 980 + animationPhase) * size * 0.013;
@@ -25769,7 +25336,7 @@ function resolveVisibleBlobbyContinuousPatches(options) {
25769
25336
  projectScenePoint(transformedCorners[2], size, sceneCenterX, sceneCenterY),
25770
25337
  projectScenePoint(transformedCorners[3], size, sceneCenterX, sceneCenterY),
25771
25338
  ];
25772
- const lightIntensity = clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION), -1, 1);
25339
+ const lightIntensity = clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$1), -1, 1);
25773
25340
  const rimLightIntensity = Math.pow(clampNumber$1(dotProduct3D(surfaceNormal, RIM_LIGHT_DIRECTION), 0, 1), 2.6);
25774
25341
  surfacePatches.push({
25775
25342
  corners: projectedCorners,
@@ -25842,10 +25409,7 @@ function sampleBlobbyContinuousSurfacePointWithLongitudeCache(options, latitude,
25842
25409
  Math.max(0, Math.cos(effectiveLongitude)) * 0.12 +
25843
25410
  lowerBlend * tentacleInfluence.core * (0.12 + tentacleInfluence.depthScale * 0.07) -
25844
25411
  Math.max(0, -Math.cos(effectiveLongitude)) * 0.05;
25845
- const tentacleTubeRadius = lowerBlend *
25846
- tentacleInfluence.core *
25847
- (0.12 + tipBlend * 0.07 + tentacleInfluence.widthScale * 0.028) *
25848
- radiusX;
25412
+ const tentacleTubeRadius = lowerBlend * tentacleInfluence.core * (0.12 + tipBlend * 0.07 + tentacleInfluence.widthScale * 0.028) * radiusX;
25849
25413
  const planarRadiusX = cosineLatitude * radiusX * horizontalScale + tentacleTubeRadius;
25850
25414
  const planarRadiusZ = cosineLatitude * radiusZ * depthScale + tentacleTubeRadius * 0.74;
25851
25415
  const lowerDrop = lowerBlend *
@@ -25857,9 +25421,7 @@ function sampleBlobbyContinuousSurfacePointWithLongitudeCache(options, latitude,
25857
25421
  (morphologyProfile.tentacles.flowLengthScale - 1) * 0.1));
25858
25422
  const combinedTentacleSway = (primaryTentacleWave + secondaryTentacleWave) * radiusX * (0.06 + tipBlend * 0.06);
25859
25423
  return {
25860
- x: Math.sin(effectiveLongitude) * planarRadiusX +
25861
- combinedTentacleSway +
25862
- tentacleCurl * radiusX * 0.18,
25424
+ x: Math.sin(effectiveLongitude) * planarRadiusX + combinedTentacleSway + tentacleCurl * radiusX * 0.18,
25863
25425
  y: Math.sin(latitude) * radiusY * (1 + upperBlend * 0.14) -
25864
25426
  upperBlend * radiusY * 0.12 +
25865
25427
  lowerDrop +
@@ -26173,6 +25735,445 @@ function formatAlphaHex(opacity) {
26173
25735
  .padStart(2, '0');
26174
25736
  }
26175
25737
 
25738
+ /* eslint-disable no-magic-numbers */
25739
+ /**
25740
+ * Light direction used by the organic 3D octopus shading.
25741
+ *
25742
+ * @private helper of `octopus3dAvatarVisual`
25743
+ */
25744
+ const LIGHT_DIRECTION = normalizeVector3({
25745
+ x: 0.48,
25746
+ y: -0.62,
25747
+ z: 0.94,
25748
+ });
25749
+ /**
25750
+ * Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
25751
+ *
25752
+ * @private helper of `octopus3dAvatarVisual`
25753
+ */
25754
+ const octopus3dStableStateCache = new WeakMap();
25755
+ /**
25756
+ * Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
25757
+ *
25758
+ * @private helper of `octopus3dAvatarVisual`
25759
+ */
25760
+ function getOctopus3dStableState(createRandom) {
25761
+ const cached = octopus3dStableStateCache.get(createRandom);
25762
+ if (cached !== undefined) {
25763
+ return cached;
25764
+ }
25765
+ const animationRandom = createRandom('octopus3d-animation-profile');
25766
+ const eyeRandom = createRandom('octopus3d-eye-profile');
25767
+ const leftEyePhaseOffset = eyeRandom() * 0.6;
25768
+ const rightEyePhaseOffset = eyeRandom() * 0.6;
25769
+ const state = {
25770
+ morphologyProfile: createOctopus3MorphologyProfile(createRandom),
25771
+ animationPhase: animationRandom() * Math.PI * 2,
25772
+ leftEyePhaseOffset,
25773
+ rightEyePhaseOffset,
25774
+ };
25775
+ octopus3dStableStateCache.set(createRandom, state);
25776
+ return state;
25777
+ }
25778
+ /**
25779
+ * Proper 3D Octopus visual built from projected organic meshes and tentacles.
25780
+ *
25781
+ * @private built-in avatar visual
25782
+ */
25783
+ const octopus3dAvatarVisual = {
25784
+ id: 'octopus3d',
25785
+ title: 'Octopus 3D',
25786
+ description: 'Proper 3D octopus portrait with a turning silhouette, expressive eyes, and depth-sorted tentacles.',
25787
+ isAnimated: true,
25788
+ supportsPointerTracking: true,
25789
+ render({ context, size, palette, createRandom, timeMs, interaction }) {
25790
+ const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3dStableState(createRandom);
25791
+ const sceneCenterX = size * 0.5;
25792
+ const sceneCenterY = size * 0.56;
25793
+ const bob = Math.sin(timeMs / 920 + animationPhase) * size * 0.014;
25794
+ const mantleCenter = {
25795
+ x: interaction.bodyOffsetX * size * 0.042 + size * morphologyProfile.body.centerXJitterRatio * 0.65,
25796
+ y: -size * 0.09 + interaction.bodyOffsetY * size * 0.028 + bob,
25797
+ z: interaction.intensity * size * 0.012,
25798
+ };
25799
+ const underbodyCenter = {
25800
+ x: mantleCenter.x * 0.86,
25801
+ y: mantleCenter.y + size * 0.168,
25802
+ z: mantleCenter.z - size * 0.018,
25803
+ };
25804
+ const mantleRadiusX = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.horizontalStretch;
25805
+ const mantleRadiusY = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.verticalStretch * 1.1;
25806
+ const mantleRadiusZ = size *
25807
+ morphologyProfile.body.bodyRadiusRatio *
25808
+ (0.9 + (morphologyProfile.body.horizontalStretch - 1) * 0.3);
25809
+ const underbodyRadiusX = mantleRadiusX * (0.9 + (morphologyProfile.tentacles.rootSpreadScale - 1) * 0.08);
25810
+ const underbodyRadiusY = mantleRadiusY * (0.44 + morphologyProfile.body.lowerDropRatio * 3.1);
25811
+ const underbodyRadiusZ = mantleRadiusZ * 0.78;
25812
+ const bodyYaw = -0.18 +
25813
+ Math.sin(timeMs / 2400 + animationPhase) * 0.05 +
25814
+ interaction.bodyOffsetX * 0.18 +
25815
+ interaction.gazeX * 0.22;
25816
+ const bodyPitch = -0.08 +
25817
+ Math.cos(timeMs / 2700 + animationPhase * 0.6) * 0.025 -
25818
+ interaction.bodyOffsetY * 0.08 -
25819
+ interaction.gazeY * 0.08;
25820
+ const headYaw = bodyYaw - 0.04 + interaction.gazeX * 0.56;
25821
+ const headPitch = bodyPitch - 0.02 - interaction.gazeY * 0.32;
25822
+ const mantlePatches = resolveVisibleEllipsoidPatches({
25823
+ center: mantleCenter,
25824
+ radiusX: mantleRadiusX,
25825
+ radiusY: mantleRadiusY,
25826
+ radiusZ: mantleRadiusZ,
25827
+ rotationX: headPitch,
25828
+ rotationY: headYaw,
25829
+ sceneCenterX,
25830
+ sceneCenterY,
25831
+ size,
25832
+ palette,
25833
+ verticalColorBias: 0,
25834
+ outlineColor: `${palette.highlight}7a`,
25835
+ });
25836
+ const underbodyPatches = resolveVisibleEllipsoidPatches({
25837
+ center: underbodyCenter,
25838
+ radiusX: underbodyRadiusX,
25839
+ radiusY: underbodyRadiusY,
25840
+ radiusZ: underbodyRadiusZ,
25841
+ rotationX: bodyPitch,
25842
+ rotationY: bodyYaw,
25843
+ sceneCenterX,
25844
+ sceneCenterY,
25845
+ size,
25846
+ palette,
25847
+ verticalColorBias: 0.18,
25848
+ outlineColor: `${palette.shadow}8f`,
25849
+ });
25850
+ const tentacleStrokes = createOctopusTentacleStrokes({
25851
+ createRandom,
25852
+ morphologyProfile,
25853
+ timeMs,
25854
+ size,
25855
+ center: underbodyCenter,
25856
+ radiusX: underbodyRadiusX,
25857
+ radiusY: underbodyRadiusY,
25858
+ radiusZ: underbodyRadiusZ,
25859
+ rotationX: bodyPitch,
25860
+ rotationY: bodyYaw,
25861
+ sceneCenterX,
25862
+ sceneCenterY,
25863
+ animationPhase,
25864
+ });
25865
+ const faceEyeSpacing = size * morphologyProfile.face.eyeSpacingRatio * 0.92;
25866
+ const faceEyeYOffset = size * morphologyProfile.face.eyeCenterYOffsetRatio - mantleRadiusY * 0.02;
25867
+ const faceEyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio * 0.82;
25868
+ const faceEyeRadiusY = faceEyeRadiusX * morphologyProfile.face.eyeHeightRatio * 0.96;
25869
+ const mouthHalfWidth = size * morphologyProfile.face.mouthWidthRatio * 0.92;
25870
+ const mouthY = size * morphologyProfile.face.mouthYOffsetRatio + mantleRadiusY * 0.08;
25871
+ drawAvatarFrame(context, size, palette);
25872
+ drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs);
25873
+ drawOctopus3dShadow(context, size, palette, interaction, timeMs);
25874
+ for (const tentacleStroke of tentacleStrokes.filter((candidateTentacleStroke) => !candidateTentacleStroke.isFrontFacing)) {
25875
+ drawTentacleStroke(context, tentacleStroke, palette);
25876
+ }
25877
+ for (const surfacePatch of [...mantlePatches, ...underbodyPatches].sort((firstSurfacePatch, secondSurfacePatch) => firstSurfacePatch.averageDepth - secondSurfacePatch.averageDepth)) {
25878
+ drawSurfacePatch(context, surfacePatch);
25879
+ }
25880
+ for (const tentacleStroke of tentacleStrokes.filter((candidateTentacleStroke) => candidateTentacleStroke.isFrontFacing)) {
25881
+ drawTentacleStroke(context, tentacleStroke, palette);
25882
+ }
25883
+ drawProjectedOrganicEye(context, {
25884
+ x: -faceEyeSpacing,
25885
+ y: faceEyeYOffset,
25886
+ z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -faceEyeSpacing, faceEyeYOffset),
25887
+ }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
25888
+ drawProjectedOrganicEye(context, {
25889
+ x: faceEyeSpacing,
25890
+ y: faceEyeYOffset,
25891
+ z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
25892
+ }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
25893
+ drawProjectedOrganicMouth(context, [
25894
+ {
25895
+ x: -mouthHalfWidth,
25896
+ y: mouthY,
25897
+ z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -mouthHalfWidth, mouthY),
25898
+ },
25899
+ {
25900
+ x: size * morphologyProfile.face.mouthCenterOffsetRatio,
25901
+ y: mouthY +
25902
+ size * morphologyProfile.face.mouthCurveDepthRatio * 0.38 +
25903
+ Math.sin(timeMs / 760 + animationPhase) * size * 0.01 +
25904
+ interaction.gazeY * size * 0.01,
25905
+ z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, size * morphologyProfile.face.mouthCenterOffsetRatio, mouthY),
25906
+ },
25907
+ {
25908
+ x: mouthHalfWidth,
25909
+ y: mouthY,
25910
+ z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, mouthHalfWidth, mouthY),
25911
+ },
25912
+ ], mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, palette, size);
25913
+ },
25914
+ };
25915
+ /**
25916
+ * Draws the atmospheric underwater glow behind the octopus mesh.
25917
+ *
25918
+ * @private helper of `octopus3dAvatarVisual`
25919
+ */
25920
+ function drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs) {
25921
+ const glowGradient = context.createRadialGradient(sceneCenterX + interaction.gazeX * size * 0.1, sceneCenterY - size * 0.2 + interaction.gazeY * size * 0.05, size * 0.04, sceneCenterX, sceneCenterY - size * 0.04, size * 0.62);
25922
+ glowGradient.addColorStop(0, `${palette.highlight}5c`);
25923
+ glowGradient.addColorStop(0.36, `${palette.accent}24`);
25924
+ glowGradient.addColorStop(1, `${palette.highlight}00`);
25925
+ context.fillStyle = glowGradient;
25926
+ context.fillRect(0, 0, size, size);
25927
+ const lowerGradient = context.createRadialGradient(sceneCenterX + Math.sin(timeMs / 1700) * size * 0.05, sceneCenterY + size * 0.23, size * 0.08, sceneCenterX, sceneCenterY + size * 0.28, size * 0.5);
25928
+ lowerGradient.addColorStop(0, `${palette.secondary}1d`);
25929
+ lowerGradient.addColorStop(1, `${palette.secondary}00`);
25930
+ context.fillStyle = lowerGradient;
25931
+ context.fillRect(0, 0, size, size);
25932
+ }
25933
+ /**
25934
+ * Draws the soft ground shadow below the octopus.
25935
+ *
25936
+ * Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
25937
+ * blurry ellipse without triggering a costly software rasterization pass on every frame.
25938
+ *
25939
+ * @private helper of `octopus3dAvatarVisual`
25940
+ */
25941
+ function drawOctopus3dShadow(context, size, palette, interaction, timeMs) {
25942
+ const cx = size * 0.5 + interaction.gazeX * size * 0.04;
25943
+ const cy = size * 0.87 + Math.sin(timeMs / 920) * size * 0.008;
25944
+ const rx = size * (0.18 + interaction.intensity * 0.02);
25945
+ const ry = size * 0.06;
25946
+ context.save();
25947
+ context.translate(cx, cy);
25948
+ context.scale(1, ry / rx);
25949
+ const blurRadius = rx * 1.4;
25950
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
25951
+ shadowGradient.addColorStop(0, `${palette.shadow}7a`);
25952
+ shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
25953
+ shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
25954
+ shadowGradient.addColorStop(1, `${palette.shadow}00`);
25955
+ context.fillStyle = shadowGradient;
25956
+ context.beginPath();
25957
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
25958
+ context.fill();
25959
+ context.restore();
25960
+ }
25961
+ /**
25962
+ * Resolves visible projected patches for one rotated ellipsoid mesh.
25963
+ *
25964
+ * @private helper of `octopus3dAvatarVisual`
25965
+ */
25966
+ function resolveVisibleEllipsoidPatches(options) {
25967
+ const { center, radiusX, radiusY, radiusZ, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, verticalColorBias, outlineColor, } = options;
25968
+ const latitudePatchCount = 10;
25969
+ const longitudePatchCount = 18;
25970
+ const surfacePatches = [];
25971
+ for (let latitudeIndex = 0; latitudeIndex < latitudePatchCount; latitudeIndex++) {
25972
+ const startLatitude = -Math.PI / 2 + (latitudeIndex / latitudePatchCount) * Math.PI;
25973
+ const endLatitude = -Math.PI / 2 + ((latitudeIndex + 1) / latitudePatchCount) * Math.PI;
25974
+ const verticalProgress = (latitudeIndex + 0.5) / latitudePatchCount;
25975
+ for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
25976
+ const startLongitude = -Math.PI + (longitudeIndex / longitudePatchCount) * Math.PI * 2;
25977
+ const endLongitude = -Math.PI + ((longitudeIndex + 1) / longitudePatchCount) * Math.PI * 2;
25978
+ const localCorners = [
25979
+ sampleEllipsoidPoint(radiusX, radiusY, radiusZ, startLatitude, startLongitude),
25980
+ sampleEllipsoidPoint(radiusX, radiusY, radiusZ, startLatitude, endLongitude),
25981
+ sampleEllipsoidPoint(radiusX, radiusY, radiusZ, endLatitude, endLongitude),
25982
+ sampleEllipsoidPoint(radiusX, radiusY, radiusZ, endLatitude, startLongitude),
25983
+ ];
25984
+ const transformedCorners = localCorners.map((localCorner) => transformScenePoint(localCorner, center, rotationX, rotationY));
25985
+ const surfaceNormal = normalizeVector3(crossProduct3D(subtractPoint3D(transformedCorners[1], transformedCorners[0]), subtractPoint3D(transformedCorners[2], transformedCorners[0])));
25986
+ if (surfaceNormal.z <= 0.01) {
25987
+ continue;
25988
+ }
25989
+ const projectedCorners = transformedCorners.map((transformedCorner) => projectScenePoint(transformedCorner, size, sceneCenterX, sceneCenterY));
25990
+ surfacePatches.push({
25991
+ corners: projectedCorners,
25992
+ averageDepth: transformedCorners.reduce((depthSum, transformedCorner) => depthSum + transformedCorner.z, 0) /
25993
+ transformedCorners.length,
25994
+ lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION), -1, 1),
25995
+ fillStyle: resolveSurfacePatchFillStyle(palette, verticalProgress + verticalColorBias),
25996
+ outlineColor,
25997
+ });
25998
+ }
25999
+ }
26000
+ return surfacePatches;
26001
+ }
26002
+ /**
26003
+ * Samples one point on an ellipsoid aligned to the local axes.
26004
+ *
26005
+ * @private helper of `octopus3dAvatarVisual`
26006
+ */
26007
+ function sampleEllipsoidPoint(radiusX, radiusY, radiusZ, latitude, longitude) {
26008
+ const cosineLatitude = Math.cos(latitude);
26009
+ return {
26010
+ x: Math.sin(longitude) * cosineLatitude * radiusX,
26011
+ y: Math.sin(latitude) * radiusY,
26012
+ z: Math.cos(longitude) * cosineLatitude * radiusZ,
26013
+ };
26014
+ }
26015
+ /**
26016
+ * Resolves one base fill tone for a surface patch across the octopus body.
26017
+ *
26018
+ * @private helper of `octopus3dAvatarVisual`
26019
+ */
26020
+ function resolveSurfacePatchFillStyle(palette, verticalProgress) {
26021
+ const clampedVerticalProgress = clampNumber$1(verticalProgress, 0, 1);
26022
+ if (clampedVerticalProgress < 0.2) {
26023
+ return palette.highlight;
26024
+ }
26025
+ if (clampedVerticalProgress < 0.45) {
26026
+ return palette.secondary;
26027
+ }
26028
+ if (clampedVerticalProgress < 0.8) {
26029
+ return palette.primary;
26030
+ }
26031
+ return `${palette.shadow}f2`;
26032
+ }
26033
+ /**
26034
+ * Draws one projected mesh patch with organic shading.
26035
+ *
26036
+ * @private helper of `octopus3dAvatarVisual`
26037
+ */
26038
+ function drawSurfacePatch(context, surfacePatch) {
26039
+ drawProjectedQuad(context, surfacePatch.corners, surfacePatch.fillStyle);
26040
+ if (surfacePatch.lightIntensity > 0) {
26041
+ drawProjectedQuad(context, surfacePatch.corners, `rgba(255, 255, 255, ${0.15 * surfacePatch.lightIntensity})`);
26042
+ }
26043
+ else if (surfacePatch.lightIntensity < 0) {
26044
+ drawProjectedQuad(context, surfacePatch.corners, `rgba(0, 0, 0, ${0.24 * Math.abs(surfacePatch.lightIntensity)})`);
26045
+ }
26046
+ context.save();
26047
+ context.beginPath();
26048
+ context.moveTo(surfacePatch.corners[0].x, surfacePatch.corners[0].y);
26049
+ for (let cornerIndex = 1; cornerIndex < surfacePatch.corners.length; cornerIndex++) {
26050
+ context.lineTo(surfacePatch.corners[cornerIndex].x, surfacePatch.corners[cornerIndex].y);
26051
+ }
26052
+ context.closePath();
26053
+ context.strokeStyle = surfacePatch.outlineColor;
26054
+ context.lineWidth = Math.max(1, getProjectedQuadPerimeter(surfacePatch.corners) * 0.0044);
26055
+ context.lineJoin = 'round';
26056
+ context.stroke();
26057
+ context.restore();
26058
+ }
26059
+ /**
26060
+ * Creates the projected 3D tentacle strokes orbiting around the lower octopus body.
26061
+ *
26062
+ * @private helper of `octopus3dAvatarVisual`
26063
+ */
26064
+ function createOctopusTentacleStrokes(options) {
26065
+ const { createRandom, morphologyProfile, timeMs, size, center, radiusX, radiusY, radiusZ, rotationX, rotationY, sceneCenterX, sceneCenterY, animationPhase, } = options;
26066
+ return Array.from({ length: morphologyProfile.tentacles.count }, (_, tentacleIndex) => {
26067
+ const tentacleRandom = createRandom(`octopus3d-tentacle-${tentacleIndex}`);
26068
+ const spreadProgress = morphologyProfile.tentacles.count === 1 ? 0.5 : tentacleIndex / (morphologyProfile.tentacles.count - 1);
26069
+ const orbitAngle = -Math.PI * 0.92 + spreadProgress * Math.PI * 1.84 + (tentacleRandom() - 0.5) * 0.16;
26070
+ const flowLength = size * (0.19 + morphologyProfile.tentacles.flowLengthScale * 0.075 + tentacleRandom() * 0.018);
26071
+ const lateralReach = size *
26072
+ (0.08 + morphologyProfile.tentacles.lateralReachScale * 0.05 + Math.abs(Math.sin(orbitAngle)) * 0.018);
26073
+ const depthReach = size * (0.028 + morphologyProfile.tentacles.tipReachScale * 0.032);
26074
+ const sway = Math.sin(timeMs / (760 + tentacleIndex * 36) + animationPhase + tentacleRandom() * Math.PI * 2);
26075
+ const anchorPoint = {
26076
+ x: Math.sin(orbitAngle) * radiusX * (0.84 + tentacleRandom() * 0.08),
26077
+ y: radiusY * (0.22 + tentacleRandom() * 0.18),
26078
+ z: Math.cos(orbitAngle) * radiusZ * (0.72 + tentacleRandom() * 0.12),
26079
+ };
26080
+ const controlPointOne = {
26081
+ x: anchorPoint.x + Math.sin(orbitAngle) * lateralReach * 0.44,
26082
+ y: anchorPoint.y + flowLength * 0.26,
26083
+ z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.3 + sway * size * 0.012,
26084
+ };
26085
+ const controlPointTwo = {
26086
+ x: anchorPoint.x +
26087
+ Math.sin(orbitAngle) * lateralReach * (0.82 + morphologyProfile.tentacles.swayScale * 0.12),
26088
+ y: anchorPoint.y + flowLength * 0.66,
26089
+ z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.72 + sway * size * 0.02,
26090
+ };
26091
+ const endPoint = {
26092
+ x: anchorPoint.x +
26093
+ Math.sin(orbitAngle) * lateralReach * (1.02 + morphologyProfile.tentacles.tipWidthScale * 0.12) +
26094
+ sway * size * 0.028,
26095
+ y: anchorPoint.y + flowLength,
26096
+ z: anchorPoint.z + Math.cos(orbitAngle) * depthReach + sway * size * 0.016,
26097
+ };
26098
+ const scenePoints = Array.from({ length: 12 }, (_, sampleIndex) => transformScenePoint(sampleCubicBezierPoint3D(anchorPoint, controlPointOne, controlPointTwo, endPoint, sampleIndex / 11), center, rotationX, rotationY));
26099
+ const projectedPoints = scenePoints.map((scenePoint) => projectScenePoint(scenePoint, size, sceneCenterX, sceneCenterY));
26100
+ const averageDepth = scenePoints.reduce((depthSum, scenePoint) => depthSum + scenePoint.z, 0) / scenePoints.length;
26101
+ return {
26102
+ projectedPoints,
26103
+ averageDepth,
26104
+ isFrontFacing: averageDepth >= center.z - size * 0.006,
26105
+ baseWidth: size *
26106
+ (0.019 +
26107
+ morphologyProfile.tentacles.baseWidthScale * 0.007 +
26108
+ tentacleRandom() * 0.003 +
26109
+ Math.abs(Math.sin(orbitAngle)) * 0.002),
26110
+ tipWidth: size * (0.0046 + morphologyProfile.tentacles.tipWidthScale * 0.0018),
26111
+ colorBias: tentacleRandom(),
26112
+ };
26113
+ });
26114
+ }
26115
+ /**
26116
+ * Samples one point on a cubic Bezier curve in 3D.
26117
+ *
26118
+ * @private helper of `octopus3dAvatarVisual`
26119
+ */
26120
+ function sampleCubicBezierPoint3D(startPoint, controlPointOne, controlPointTwo, endPoint, progress) {
26121
+ const inverseProgress = 1 - progress;
26122
+ return {
26123
+ x: inverseProgress * inverseProgress * inverseProgress * startPoint.x +
26124
+ 3 * inverseProgress * inverseProgress * progress * controlPointOne.x +
26125
+ 3 * inverseProgress * progress * progress * controlPointTwo.x +
26126
+ progress * progress * progress * endPoint.x,
26127
+ y: inverseProgress * inverseProgress * inverseProgress * startPoint.y +
26128
+ 3 * inverseProgress * inverseProgress * progress * controlPointOne.y +
26129
+ 3 * inverseProgress * progress * progress * controlPointTwo.y +
26130
+ progress * progress * progress * endPoint.y,
26131
+ z: inverseProgress * inverseProgress * inverseProgress * startPoint.z +
26132
+ 3 * inverseProgress * inverseProgress * progress * controlPointOne.z +
26133
+ 3 * inverseProgress * progress * progress * controlPointTwo.z +
26134
+ progress * progress * progress * endPoint.z,
26135
+ };
26136
+ }
26137
+ /**
26138
+ * Draws one projected tentacle stroke with a slim highlight ridge.
26139
+ *
26140
+ * @private helper of `octopus3dAvatarVisual`
26141
+ */
26142
+ function drawTentacleStroke(context, tentacleStroke, palette) {
26143
+ const projectedSegments = tentacleStroke.projectedPoints.length - 1;
26144
+ for (let segmentIndex = 0; segmentIndex < projectedSegments; segmentIndex++) {
26145
+ const startPoint = tentacleStroke.projectedPoints[segmentIndex];
26146
+ const endPoint = tentacleStroke.projectedPoints[segmentIndex + 1];
26147
+ const progress = segmentIndex / projectedSegments;
26148
+ const width = tentacleStroke.baseWidth + (tentacleStroke.tipWidth - tentacleStroke.baseWidth) * progress;
26149
+ context.beginPath();
26150
+ context.moveTo(startPoint.x, startPoint.y);
26151
+ context.lineTo(endPoint.x, endPoint.y);
26152
+ context.strokeStyle = tentacleStroke.colorBias > 0.6 ? `${palette.secondary}f0` : `${palette.primary}f0`;
26153
+ context.lineWidth = width;
26154
+ context.lineCap = 'round';
26155
+ context.stroke();
26156
+ context.beginPath();
26157
+ context.moveTo(startPoint.x, startPoint.y);
26158
+ context.lineTo(endPoint.x, endPoint.y);
26159
+ context.strokeStyle = tentacleStroke.isFrontFacing ? `${palette.highlight}80` : `${palette.highlight}40`;
26160
+ context.lineWidth = Math.max(1, width * 0.34);
26161
+ context.lineCap = 'round';
26162
+ context.stroke();
26163
+ }
26164
+ }
26165
+ /**
26166
+ * Resolves the front surface depth on an ellipsoid for one local face point.
26167
+ *
26168
+ * @private helper of `octopus3dAvatarVisual`
26169
+ */
26170
+ function resolveEllipsoidSurfaceDepth(radiusX, radiusY, radiusZ, x, y) {
26171
+ const normalizedX = x / radiusX;
26172
+ const normalizedY = y / radiusY;
26173
+ const remainingDepthRatio = Math.max(0, 1 - normalizedX * normalizedX - normalizedY * normalizedY);
26174
+ return Math.sqrt(remainingDepthRatio) * radiusZ;
26175
+ }
26176
+
26176
26177
  /* eslint-disable no-magic-numbers */
26177
26178
  /**
26178
26179
  * Octopus avatar visual.
@@ -26993,14 +26994,14 @@ function resolveAvatarVisualId(value) {
26993
26994
  /**
26994
26995
  * META AVATAR commitment definition
26995
26996
  *
26996
- * The `META AVATAR` commitment sets the built-in default avatar visual used when
26997
- * the agent does not provide an explicit `META IMAGE`.
26997
+ * The `META AVATAR` and `META VISUAL` commitments set the built-in default avatar visual
26998
+ * used when the agent does not provide an explicit `META IMAGE`.
26998
26999
  *
26999
27000
  * @private [🪔] Maybe export the commitments through some package
27000
27001
  */
27001
27002
  class MetaAvatarCommitmentDefinition extends BaseCommitmentDefinition {
27002
- constructor() {
27003
- super('META AVATAR');
27003
+ constructor(type = 'META AVATAR') {
27004
+ super(type);
27004
27005
  }
27005
27006
  /**
27006
27007
  * Short one-line description of META AVATAR.
@@ -27020,14 +27021,15 @@ class MetaAvatarCommitmentDefinition extends BaseCommitmentDefinition {
27020
27021
  get documentation() {
27021
27022
  const supportedVisuals = AVATAR_VISUALS.map((avatarVisual) => `\`${avatarVisual.id}\``).join(', ');
27022
27023
  return spaceTrim$1(`
27023
- # META AVATAR
27024
+ # ${this.type}
27024
27025
 
27025
27026
  Sets the built-in avatar visual used for the agent when no explicit \`META IMAGE\` is provided.
27027
+ \`META AVATAR\` and \`META VISUAL\` are equivalent.
27026
27028
 
27027
27029
  ## Key aspects
27028
27030
 
27029
27031
  - Does not modify the agent's behavior or responses.
27030
- - Only one \`META AVATAR\` should be used per agent.
27032
+ - Only one \`META AVATAR\` or \`META VISUAL\` should be used per agent.
27031
27033
  - If multiple are specified, the last one takes precedence.
27032
27034
  - Values are matched case-insensitively and spaces, hyphens, and underscores are normalized.
27033
27035
  - Supported visuals are derived from the shared avatar registry: ${supportedVisuals}.
@@ -27042,15 +27044,15 @@ class MetaAvatarCommitmentDefinition extends BaseCommitmentDefinition {
27042
27044
  \`\`\`
27043
27045
 
27044
27046
  \`\`\`book
27045
- Orb Assistant
27047
+ Minecraft Assistant
27046
27048
 
27047
- META AVATAR orb
27049
+ META VISUAL Minecraft2
27048
27050
  GOAL Answer in a calm and focused way.
27049
27051
  \`\`\`
27050
27052
  `);
27051
27053
  }
27052
27054
  applyToAgentModelRequirements(requirements, content) {
27053
- // META AVATAR doesn't modify the system message or model requirements.
27055
+ // META AVATAR and META VISUAL don't modify the system message or model requirements.
27054
27056
  // It's handled separately in the parsing logic for profile avatar resolution.
27055
27057
  return requirements;
27056
27058
  }
@@ -29029,10 +29031,10 @@ const teamToolTitles = {};
29029
29031
  *
29030
29032
  * @private
29031
29033
  */
29032
- const TEAM_SYSTEM_MESSAGE_GUIDANCE_LINES = [
29033
- '- If a teammate is relevant to the request, consult that teammate using the matching tool.',
29034
- '- Do not ask the user for information that a listed teammate can provide directly.',
29035
- ];
29034
+ const TEAM_SYSTEM_MESSAGE_GUIDANCE = spaceTrim$1(`
29035
+ - If a teammate is relevant to the request, consult that teammate using the matching tool.
29036
+ - Do not ask the user for information that a listed teammate can provide directly.
29037
+ `);
29036
29038
  /**
29037
29039
  * Constant for remote agents by Url.
29038
29040
  */
@@ -29214,7 +29216,7 @@ function buildTeamSystemMessageBody(teamEntries) {
29214
29216
  `);
29215
29217
  });
29216
29218
  return spaceTrim$1((block) => `
29217
- ${block(TEAM_SYSTEM_MESSAGE_GUIDANCE_LINES.join('\n'))}
29219
+ ${block(TEAM_SYSTEM_MESSAGE_GUIDANCE)}
29218
29220
 
29219
29221
  ${block(teammateSections.join('\n\n'))}
29220
29222
  `);
@@ -36191,6 +36193,7 @@ const COMMITMENT_REGISTRY = [
36191
36193
  new ActionCommitmentDefinition('ACTIONS'),
36192
36194
  new ComponentCommitmentDefinition(),
36193
36195
  new MetaAvatarCommitmentDefinition(),
36196
+ new MetaAvatarCommitmentDefinition('META VISUAL'),
36194
36197
  new MetaImageCommitmentDefinition(),
36195
36198
  new MetaColorCommitmentDefinition(),
36196
36199
  new MetaFontCommitmentDefinition(),
@@ -37542,6 +37545,7 @@ function hasHttpProtocol(value) {
37542
37545
  */
37543
37546
  const META_COMMITMENT_APPLIERS = {
37544
37547
  'META AVATAR': applyMetaAvatarContent,
37548
+ 'META VISUAL': applyMetaAvatarContent,
37545
37549
  'META LINK': applyMetaLinkContent,
37546
37550
  'META DOMAIN': applyMetaDomainContent,
37547
37551
  'META IMAGE': applyMetaImageContent,
@@ -37590,7 +37594,7 @@ function applyGenericMetaCommitment(state, content) {
37590
37594
  state.meta[metaType] = metaValue;
37591
37595
  }
37592
37596
  /**
37593
- * Applies META AVATAR content into the canonical `meta.avatar` field.
37597
+ * Applies META AVATAR / META VISUAL content into the canonical `meta.avatar` field.
37594
37598
  */
37595
37599
  function applyMetaAvatarContent(state, content) {
37596
37600
  const avatarVisualId = resolveAvatarVisualId(content);
@@ -41131,61 +41135,41 @@ function isRootPath(value) {
41131
41135
  */
41132
41136
  let $usedEnvFilename = null;
41133
41137
  /**
41134
- * Pass the `.env` file which was used to configure LLM tools
41135
- *
41136
- * Note: `$` is used to indicate that this variable is making side effect
41138
+ * Shared state for the `.env` file used to configure LLM tools.
41137
41139
  *
41138
- * @private internal log of `$provideLlmToolsConfigurationFromEnv` and `$registeredLlmToolsMessage`
41140
+ * @private internal state of `$registeredLlmToolsMessage`
41139
41141
  */
41140
- function $setUsedEnvFilename(filepath) {
41141
- $usedEnvFilename = filepath;
41142
- }
41143
- /**
41144
- * Creates a message with all registered LLM tools
41145
- *
41146
- * Note: This function is used to create a (error) message when there is no constructor for some LLM provider
41147
- *
41148
- * @private internal function of `createLlmToolsFromConfiguration` and `$provideLlmToolsFromEnv`
41149
- */
41150
- function $registeredLlmToolsMessage() {
41151
- const registeredLlmToolsMessageContext = createRegisteredLlmToolsMessageContext();
41152
- if (registeredLlmToolsMessageContext.llmToolStatuses.length === 0) {
41153
- return renderNoRegisteredLlmToolsMessage(registeredLlmToolsMessageContext.usedEnvMessage);
41154
- }
41155
- return renderRegisteredLlmToolsMessage(registeredLlmToolsMessageContext);
41156
- }
41157
- /**
41158
- * Collects all state needed to render the provider summary.
41159
- *
41160
- * @private internal function of `$registeredLlmToolsMessage`
41161
- */
41162
- function createRegisteredLlmToolsMessageContext() {
41163
- const isRunningInNode = $isRunningInNode();
41164
- const env = getAvailableEnvironmentVariables(isRunningInNode);
41165
- const registeredLlmToolRegisters = getRegisteredLlmToolRegisters();
41166
- return {
41167
- env,
41168
- llmToolStatuses: listRegisteredLlmToolStatuses(registeredLlmToolRegisters, env),
41169
- usedEnvMessage: createUsedEnvMessage(),
41170
- isRunningInNode,
41171
- };
41172
- }
41142
+ const USED_ENV_FILENAME = {
41143
+ set(filepath) {
41144
+ $usedEnvFilename = filepath;
41145
+ },
41146
+ createMessage() {
41147
+ return $usedEnvFilename === null
41148
+ ? `Unknown \`.env\` file`
41149
+ : spaceTrim$1(`
41150
+ Used \`.env\` file:
41151
+ ${$usedEnvFilename}
41152
+ `);
41153
+ },
41154
+ };
41155
+
41173
41156
  /**
41174
41157
  * Reads environment variables relevant for provider configuration.
41175
41158
  *
41176
- * @private internal function of `$registeredLlmToolsMessage`
41159
+ * @private function of `$registeredLlmToolsMessage`
41177
41160
  */
41178
- function getAvailableEnvironmentVariables(isRunningInNode) {
41161
+ function getAvailableRegisteredLlmToolsEnvironmentVariables(isRunningInNode) {
41179
41162
  if (isRunningInNode) {
41180
41163
  return process.env;
41181
41164
  // <- TODO: [⚛] Some DRY way how to get to `process.env` and pass it into functions - ACRY search for `env`
41182
41165
  }
41183
41166
  return {};
41184
41167
  }
41168
+
41185
41169
  /**
41186
41170
  * Takes stable snapshots of both LLM provider registers.
41187
41171
  *
41188
- * @private internal function of `$registeredLlmToolsMessage`
41172
+ * @private function of `$registeredLlmToolsMessage`
41189
41173
  */
41190
41174
  function getRegisteredLlmToolRegisters() {
41191
41175
  return {
@@ -41193,62 +41177,30 @@ function getRegisteredLlmToolRegisters() {
41193
41177
  registeredTools: $llmToolsRegister.list(),
41194
41178
  };
41195
41179
  }
41196
- /**
41197
- * Lists provider entries enriched with installation and configuration state.
41198
- *
41199
- * @private internal function of `$registeredLlmToolsMessage`
41200
- */
41201
- function listRegisteredLlmToolStatuses({ registeredMetadata, registeredTools }, env) {
41202
- return listRegisteredLlmToolEntries(registeredMetadata, registeredTools).map((registeredLlmToolEntry) => createRegisteredLlmToolStatus({ registeredLlmToolEntry, registeredMetadata, registeredTools, env }));
41203
- }
41204
- /**
41205
- * Merges provider entries from the metadata and constructor registers.
41206
- *
41207
- * @private internal function of `$registeredLlmToolsMessage`
41208
- */
41209
- function listRegisteredLlmToolEntries(registeredMetadata, registeredTools) {
41210
- const registeredLlmToolEntries = new Map();
41211
- for (const { title, packageName, className, envVariables } of registeredMetadata) {
41212
- addRegisteredLlmToolEntry(registeredLlmToolEntries, { title, packageName, className, envVariables });
41213
- }
41214
- for (const { packageName, className } of registeredTools) {
41215
- addRegisteredLlmToolEntry(registeredLlmToolEntries, { packageName, className });
41216
- }
41217
- return [...registeredLlmToolEntries.values()];
41218
- }
41219
- /**
41220
- * Adds a provider entry only when the provider is not already present.
41221
- *
41222
- * @private internal function of `$registeredLlmToolsMessage`
41223
- */
41224
- function addRegisteredLlmToolEntry(registeredLlmToolEntries, registeredLlmToolEntry) {
41225
- const registeredLlmToolEntryKey = createRegisteredLlmToolEntryKey(registeredLlmToolEntry);
41226
- if (registeredLlmToolEntries.has(registeredLlmToolEntryKey)) {
41227
- return;
41228
- }
41229
- registeredLlmToolEntries.set(registeredLlmToolEntryKey, registeredLlmToolEntry);
41230
- }
41180
+
41231
41181
  /**
41232
41182
  * Creates a deduplication key for a provider entry.
41233
41183
  *
41234
- * @private internal function of `$registeredLlmToolsMessage`
41184
+ * @private function of `$registeredLlmToolsMessage`
41235
41185
  */
41236
41186
  function createRegisteredLlmToolEntryKey({ packageName, className }) {
41237
41187
  return `${packageName}::${className}`;
41238
41188
  }
41189
+
41239
41190
  /**
41240
41191
  * Checks whether the given provider entry already exists in the target register list.
41241
41192
  *
41242
- * @private internal function of `$registeredLlmToolsMessage`
41193
+ * @private function of `$registeredLlmToolsMessage`
41243
41194
  */
41244
41195
  function hasRegisteredLlmToolEntry(registeredLlmToolEntries, registeredLlmToolEntry) {
41245
41196
  const registeredLlmToolEntryKey = createRegisteredLlmToolEntryKey(registeredLlmToolEntry);
41246
41197
  return registeredLlmToolEntries.some((listedRegisteredLlmToolEntry) => createRegisteredLlmToolEntryKey(listedRegisteredLlmToolEntry) === registeredLlmToolEntryKey);
41247
41198
  }
41199
+
41248
41200
  /**
41249
41201
  * Builds the runtime status for one provider entry.
41250
41202
  *
41251
- * @private internal function of `$registeredLlmToolsMessage`
41203
+ * @private function of `$registeredLlmToolsMessage`
41252
41204
  */
41253
41205
  function createRegisteredLlmToolStatus({ registeredLlmToolEntry, registeredMetadata, registeredTools, env, }) {
41254
41206
  const availabilityStatus = createRegisteredLlmToolAvailabilityStatus(registeredLlmToolEntry, registeredMetadata, registeredTools);
@@ -41262,7 +41214,7 @@ function createRegisteredLlmToolStatus({ registeredLlmToolEntry, registeredMetad
41262
41214
  /**
41263
41215
  * Resolves whether the provider has metadata and a registered constructor.
41264
41216
  *
41265
- * @private internal function of `$registeredLlmToolsMessage`
41217
+ * @private function of `$registeredLlmToolsMessage`
41266
41218
  */
41267
41219
  function createRegisteredLlmToolAvailabilityStatus(registeredLlmToolEntry, registeredMetadata, registeredTools) {
41268
41220
  return {
@@ -41273,7 +41225,7 @@ function createRegisteredLlmToolAvailabilityStatus(registeredLlmToolEntry, regis
41273
41225
  /**
41274
41226
  * Resolves whether the provider has enough environment variables to be configured.
41275
41227
  *
41276
- * @private internal function of `$registeredLlmToolsMessage`
41228
+ * @private function of `$registeredLlmToolsMessage`
41277
41229
  */
41278
41230
  function createRegisteredLlmToolConfigurationStatus({ envVariables }, env) {
41279
41231
  return {
@@ -41284,7 +41236,7 @@ function createRegisteredLlmToolConfigurationStatus({ envVariables }, env) {
41284
41236
  /**
41285
41237
  * Checks whether all required environment variables are present for a provider.
41286
41238
  *
41287
- * @private internal function of `$registeredLlmToolsMessage`
41239
+ * @private function of `$registeredLlmToolsMessage`
41288
41240
  */
41289
41241
  function isRegisteredLlmToolFullyConfigured(envVariables, env) {
41290
41242
  if (envVariables === undefined || envVariables === null) {
@@ -41295,7 +41247,7 @@ function isRegisteredLlmToolFullyConfigured(envVariables, env) {
41295
41247
  /**
41296
41248
  * Checks whether at least one required environment variable is present for a provider.
41297
41249
  *
41298
- * @private internal function of `$registeredLlmToolsMessage`
41250
+ * @private function of `$registeredLlmToolsMessage`
41299
41251
  */
41300
41252
  function isRegisteredLlmToolPartiallyConfigured(envVariables, env) {
41301
41253
  if (envVariables === undefined || envVariables === null) {
@@ -41303,109 +41255,128 @@ function isRegisteredLlmToolPartiallyConfigured(envVariables, env) {
41303
41255
  }
41304
41256
  return envVariables.some((envVariableName) => env[envVariableName] !== undefined);
41305
41257
  }
41258
+
41306
41259
  /**
41307
- * Renders the fallback message for environments with no registered providers.
41260
+ * Merges provider entries from the metadata and constructor registers.
41308
41261
  *
41309
- * @private internal function of `$registeredLlmToolsMessage`
41262
+ * @private function of `$registeredLlmToolsMessage`
41310
41263
  */
41311
- function renderNoRegisteredLlmToolsMessage(usedEnvMessage) {
41312
- return spaceTrim$1((block) => `
41313
- No LLM providers are available.
41314
-
41315
- ${block(usedEnvMessage)}
41316
- `);
41264
+ function listRegisteredLlmToolEntries(registeredMetadata, registeredTools) {
41265
+ const registeredLlmToolEntries = new Map();
41266
+ for (const { title, packageName, className, envVariables } of registeredMetadata) {
41267
+ addRegisteredLlmToolEntry(registeredLlmToolEntries, { title, packageName, className, envVariables });
41268
+ }
41269
+ for (const { packageName, className } of registeredTools) {
41270
+ addRegisteredLlmToolEntry(registeredLlmToolEntries, { packageName, className });
41271
+ }
41272
+ return [...registeredLlmToolEntries.values()];
41317
41273
  }
41318
41274
  /**
41319
- * Renders the full provider status summary.
41275
+ * Adds a provider entry only when the provider is not already present.
41320
41276
  *
41321
- * @private internal function of `$registeredLlmToolsMessage`
41277
+ * @private function of `$registeredLlmToolsMessage`
41322
41278
  */
41323
- function renderRegisteredLlmToolsMessage({ env, llmToolStatuses, usedEnvMessage, isRunningInNode, }) {
41324
- return spaceTrim$1((block) => `
41325
-
41326
- ${block(usedEnvMessage)}
41327
-
41328
- Relevant environment variables:
41329
- ${block(renderRelevantEnvironmentVariables(env, llmToolStatuses))}
41330
-
41331
- Available LLM providers are:
41332
- ${block(renderAvailableProviders(llmToolStatuses, env, isRunningInNode))}
41333
- `);
41279
+ function addRegisteredLlmToolEntry(registeredLlmToolEntries, registeredLlmToolEntry) {
41280
+ const registeredLlmToolEntryKey = createRegisteredLlmToolEntryKey(registeredLlmToolEntry);
41281
+ if (registeredLlmToolEntries.has(registeredLlmToolEntryKey)) {
41282
+ return;
41283
+ }
41284
+ registeredLlmToolEntries.set(registeredLlmToolEntryKey, registeredLlmToolEntry);
41334
41285
  }
41286
+
41335
41287
  /**
41336
- * Renders the list of environment variables used by at least one registered provider.
41288
+ * Lists provider entries enriched with installation and configuration state.
41337
41289
  *
41338
- * @private internal function of `$registeredLlmToolsMessage`
41290
+ * @private function of `$registeredLlmToolsMessage`
41339
41291
  */
41340
- function renderRelevantEnvironmentVariables(env, llmToolStatuses) {
41341
- return listRelevantEnvironmentVariables(env, llmToolStatuses)
41342
- .map((envVariableName) => `- \`${envVariableName}\``)
41343
- .join('\n');
41292
+ function listRegisteredLlmToolStatuses({ registeredMetadata, registeredTools }, env) {
41293
+ return listRegisteredLlmToolEntries(registeredMetadata, registeredTools).map((registeredLlmToolEntry) => createRegisteredLlmToolStatus({ registeredLlmToolEntry, registeredMetadata, registeredTools, env }));
41344
41294
  }
41295
+
41345
41296
  /**
41346
- * Lists environment variables that are both present and used by at least one provider.
41297
+ * Collects all state needed to render the provider summary.
41347
41298
  *
41348
- * @private internal function of `$registeredLlmToolsMessage`
41299
+ * @private function of `$registeredLlmToolsMessage`
41349
41300
  */
41350
- function listRelevantEnvironmentVariables(env, llmToolStatuses) {
41351
- return Object.keys(env).filter((envVariableName) => llmToolStatuses.some(({ envVariables }) => envVariables === null || envVariables === void 0 ? void 0 : envVariables.includes(envVariableName)));
41301
+ function createRegisteredLlmToolsMessageContext() {
41302
+ const isRunningInNode = $isRunningInNode();
41303
+ const env = getAvailableRegisteredLlmToolsEnvironmentVariables(isRunningInNode);
41304
+ const registeredLlmToolRegisters = getRegisteredLlmToolRegisters();
41305
+ return {
41306
+ env,
41307
+ llmToolStatuses: listRegisteredLlmToolStatuses(registeredLlmToolRegisters, env),
41308
+ usedEnvMessage: USED_ENV_FILENAME.createMessage(),
41309
+ isRunningInNode,
41310
+ };
41352
41311
  }
41312
+
41353
41313
  /**
41354
- * Renders all provider lines in the status summary.
41314
+ * Renders the fallback message for environments with no registered providers.
41355
41315
  *
41356
- * @private internal function of `$registeredLlmToolsMessage`
41316
+ * @private function of `$registeredLlmToolsMessage`
41357
41317
  */
41358
- function renderAvailableProviders(llmToolStatuses, env, isRunningInNode) {
41359
- return llmToolStatuses
41360
- .map((llmToolStatus, index) => renderAvailableProvider(llmToolStatus, index, env, isRunningInNode))
41361
- .join('\n');
41318
+ function renderNoRegisteredLlmToolsMessage(usedEnvMessage) {
41319
+ return spaceTrim$1((block) => `
41320
+ No LLM providers are available.
41321
+
41322
+ ${block(usedEnvMessage)}
41323
+ `);
41362
41324
  }
41325
+
41363
41326
  /**
41364
- * Renders one provider line in the status summary.
41327
+ * Creates the configuration-status sentence for one provider.
41365
41328
  *
41366
- * @private internal function of `$registeredLlmToolsMessage`
41329
+ * @private function of `$registeredLlmToolsMessage`
41367
41330
  */
41368
- function renderAvailableProvider(llmToolStatus, index, env, isRunningInNode) {
41369
- const providerMessage = createAvailableProviderMessage(llmToolStatus, index, env);
41370
- if (!isRunningInNode) {
41371
- return providerMessage;
41331
+ function createRegisteredLlmToolConfigurationStatusMessage({ envVariables, isFullyConfigured, isPartiallyConfigured }, env) {
41332
+ if (isFullyConfigured) {
41333
+ return `Configured`;
41334
+ }
41335
+ if (isPartiallyConfigured) {
41336
+ return createPartiallyConfiguredStatusMessage(envVariables, env);
41372
41337
  }
41373
- return colorizeAvailableProviderMessage(providerMessage, llmToolStatus);
41338
+ if (envVariables !== null) {
41339
+ return createNotConfiguredStatusMessage(envVariables);
41340
+ }
41341
+ return `Not configured`;
41342
+ // <- Note: Can not be configured via environment variables
41374
41343
  }
41375
41344
  /**
41376
- * Creates the plain-text provider line before optional colorization.
41345
+ * Creates the partial-configuration sentence including missing variables.
41377
41346
  *
41378
- * @private internal function of `$registeredLlmToolsMessage`
41347
+ * @private function of `$registeredLlmToolsMessage`
41379
41348
  */
41380
- function createAvailableProviderMessage(llmToolStatus, index, env) {
41381
- const { title, packageName, className } = llmToolStatus;
41382
- const providerStatusMessages = createProviderStatusMessages(llmToolStatus, env);
41383
- return spaceTrim$1(`
41384
- ${index + 1}) **${title}** \`${className}\` from \`${packageName}\`
41385
- ${providerStatusMessages.join('; ')}
41386
- `);
41349
+ function createPartiallyConfiguredStatusMessage(envVariables, env) {
41350
+ return `Partially confugured, missing ${listMissingEnvironmentVariables(envVariables, env).join(' + ')}`;
41387
41351
  }
41388
41352
  /**
41389
- * Creates the install and configuration fragments for one provider line.
41353
+ * Creates the not-configured sentence including the expected environment variables.
41390
41354
  *
41391
- * @private internal function of `$registeredLlmToolsMessage`
41355
+ * @private function of `$registeredLlmToolsMessage`
41392
41356
  */
41393
- function createProviderStatusMessages(llmToolStatus, env) {
41394
- return [createInstallationStatusMessage(llmToolStatus), createConfigurationStatusMessage(llmToolStatus, env)];
41357
+ function createNotConfiguredStatusMessage(envVariables) {
41358
+ return `Not configured, to configure set env ${envVariables === null || envVariables === void 0 ? void 0 : envVariables.join(' + ')}`;
41395
41359
  }
41360
+ /**
41361
+ * Lists environment variables that are required but currently missing.
41362
+ *
41363
+ * @private function of `$registeredLlmToolsMessage`
41364
+ */
41365
+ function listMissingEnvironmentVariables(envVariables, env) {
41366
+ return (envVariables === null || envVariables === void 0 ? void 0 : envVariables.filter((envVariable) => env[envVariable] === undefined)) || [];
41367
+ }
41368
+
41396
41369
  /**
41397
41370
  * Creates the installation-status sentence for one provider.
41398
41371
  *
41399
- * @private internal function of `$registeredLlmToolsMessage`
41372
+ * @private function of `$registeredLlmToolsMessage`
41400
41373
  */
41401
- function createInstallationStatusMessage({ isMetadataAvailable, isInstalled, }) {
41402
- const installationStatusKey = createInstallationStatusKey(isMetadataAvailable, isInstalled);
41374
+ function createRegisteredLlmToolInstallationStatusMessage({ isMetadataAvailable, isInstalled, }) {
41375
+ const installationStatusKey = createRegisteredLlmToolInstallationStatusKey(isMetadataAvailable, isInstalled);
41403
41376
  switch (installationStatusKey) {
41404
41377
  case 'missing-metadata-and-installation':
41405
- // TODO: [�][�] Maybe do allow to do auto-install if package not registered and not found
41406
41378
  return `Not installed and no metadata, looks like a unexpected behavior`;
41407
41379
  case 'metadata-without-installation':
41408
- // TODO: [�][�]
41409
41380
  return `Not installed`;
41410
41381
  case 'installation-without-metadata':
41411
41382
  return `No metadata but installed, looks like a unexpected behavior`;
@@ -41418,9 +41389,9 @@ function createInstallationStatusMessage({ isMetadataAvailable, isInstalled, })
41418
41389
  /**
41419
41390
  * Creates a stable installation-state key from metadata and constructor availability.
41420
41391
  *
41421
- * @private internal function of `$registeredLlmToolsMessage`
41392
+ * @private function of `$registeredLlmToolsMessage`
41422
41393
  */
41423
- function createInstallationStatusKey(isMetadataAvailable, isInstalled) {
41394
+ function createRegisteredLlmToolInstallationStatusKey(isMetadataAvailable, isInstalled) {
41424
41395
  if (!isMetadataAvailable && !isInstalled) {
41425
41396
  return 'missing-metadata-and-installation';
41426
41397
  }
@@ -41435,54 +41406,59 @@ function createInstallationStatusKey(isMetadataAvailable, isInstalled) {
41435
41406
  }
41436
41407
  return 'unknown';
41437
41408
  }
41409
+
41438
41410
  /**
41439
- * Creates the configuration-status sentence for one provider.
41411
+ * Renders all provider lines in the status summary.
41440
41412
  *
41441
- * @private internal function of `$registeredLlmToolsMessage`
41413
+ * @private function of `$registeredLlmToolsMessage`
41442
41414
  */
41443
- function createConfigurationStatusMessage({ envVariables, isFullyConfigured, isPartiallyConfigured }, env) {
41444
- if (isFullyConfigured) {
41445
- return `Configured`;
41446
- }
41447
- if (isPartiallyConfigured) {
41448
- return createPartiallyConfiguredStatusMessage(envVariables, env);
41449
- }
41450
- if (envVariables !== null) {
41451
- return createNotConfiguredStatusMessage(envVariables);
41452
- }
41453
- return `Not configured`;
41454
- // <- Note: Can not be configured via environment variables
41415
+ function renderAvailableRegisteredLlmTools(llmToolStatuses, env, isRunningInNode) {
41416
+ return llmToolStatuses
41417
+ .map((llmToolStatus, index) => renderAvailableRegisteredLlmTool(llmToolStatus, index, env, isRunningInNode))
41418
+ .join('\n');
41455
41419
  }
41456
41420
  /**
41457
- * Creates the partial-configuration sentence including missing variables.
41421
+ * Renders one provider line in the status summary.
41458
41422
  *
41459
- * @private internal function of `$registeredLlmToolsMessage`
41423
+ * @private function of `$registeredLlmToolsMessage`
41460
41424
  */
41461
- function createPartiallyConfiguredStatusMessage(envVariables, env) {
41462
- return `Partially confugured, missing ${listMissingEnvironmentVariables(envVariables, env).join(' + ')}`;
41425
+ function renderAvailableRegisteredLlmTool(llmToolStatus, index, env, isRunningInNode) {
41426
+ const providerMessage = createAvailableRegisteredLlmToolMessage(llmToolStatus, index, env);
41427
+ if (!isRunningInNode) {
41428
+ return providerMessage;
41429
+ }
41430
+ return colorizeAvailableRegisteredLlmToolMessage(providerMessage, llmToolStatus);
41463
41431
  }
41464
41432
  /**
41465
- * Creates the not-configured sentence including the expected environment variables.
41433
+ * Creates the plain-text provider line before optional colorization.
41466
41434
  *
41467
- * @private internal function of `$registeredLlmToolsMessage`
41435
+ * @private function of `$registeredLlmToolsMessage`
41468
41436
  */
41469
- function createNotConfiguredStatusMessage(envVariables) {
41470
- return `Not configured, to configure set env ${envVariables === null || envVariables === void 0 ? void 0 : envVariables.join(' + ')}`;
41437
+ function createAvailableRegisteredLlmToolMessage(llmToolStatus, index, env) {
41438
+ const { title, packageName, className } = llmToolStatus;
41439
+ const providerStatusMessages = createRegisteredLlmToolStatusMessages(llmToolStatus, env);
41440
+ return spaceTrim$1(`
41441
+ ${index + 1}) **${title}** \`${className}\` from \`${packageName}\`
41442
+ ${providerStatusMessages.join('; ')}
41443
+ `);
41471
41444
  }
41472
41445
  /**
41473
- * Lists environment variables that are required but currently missing.
41446
+ * Creates the install and configuration fragments for one provider line.
41474
41447
  *
41475
- * @private internal function of `$registeredLlmToolsMessage`
41448
+ * @private function of `$registeredLlmToolsMessage`
41476
41449
  */
41477
- function listMissingEnvironmentVariables(envVariables, env) {
41478
- return (envVariables === null || envVariables === void 0 ? void 0 : envVariables.filter((envVariable) => env[envVariable] === undefined)) || [];
41450
+ function createRegisteredLlmToolStatusMessages(llmToolStatus, env) {
41451
+ return [
41452
+ createRegisteredLlmToolInstallationStatusMessage(llmToolStatus),
41453
+ createRegisteredLlmToolConfigurationStatusMessage(llmToolStatus, env),
41454
+ ];
41479
41455
  }
41480
41456
  /**
41481
41457
  * Applies the same terminal coloring rules as the original summary renderer.
41482
41458
  *
41483
- * @private internal function of `$registeredLlmToolsMessage`
41459
+ * @private function of `$registeredLlmToolsMessage`
41484
41460
  */
41485
- function colorizeAvailableProviderMessage(providerMessage, { isInstalled, isFullyConfigured, isPartiallyConfigured }) {
41461
+ function colorizeAvailableRegisteredLlmToolMessage(providerMessage, { isInstalled, isFullyConfigured, isPartiallyConfigured }) {
41486
41462
  if (isInstalled && isFullyConfigured) {
41487
41463
  return colors.green(providerMessage);
41488
41464
  }
@@ -41491,18 +41467,67 @@ function colorizeAvailableProviderMessage(providerMessage, { isInstalled, isFull
41491
41467
  }
41492
41468
  return colors.gray(providerMessage);
41493
41469
  }
41470
+
41494
41471
  /**
41495
- * Creates the `.env` origin sentence used in the summary header.
41472
+ * Renders the list of environment variables used by at least one registered provider.
41496
41473
  *
41497
- * @private internal function of `$registeredLlmToolsMessage`
41474
+ * @private function of `$registeredLlmToolsMessage`
41498
41475
  */
41499
- function createUsedEnvMessage() {
41500
- return $usedEnvFilename === null
41501
- ? `Unknown \`.env\` file`
41502
- : spaceTrim$1(`
41503
- Used \`.env\` file:
41504
- ${$usedEnvFilename}
41505
- `);
41476
+ function renderRelevantRegisteredLlmToolsEnvironmentVariables(env, llmToolStatuses) {
41477
+ return listRelevantRegisteredLlmToolsEnvironmentVariables(env, llmToolStatuses)
41478
+ .map((envVariableName) => `- \`${envVariableName}\``)
41479
+ .join('\n');
41480
+ }
41481
+ /**
41482
+ * Lists environment variables that are both present and used by at least one provider.
41483
+ *
41484
+ * @private function of `$registeredLlmToolsMessage`
41485
+ */
41486
+ function listRelevantRegisteredLlmToolsEnvironmentVariables(env, llmToolStatuses) {
41487
+ return Object.keys(env).filter((envVariableName) => llmToolStatuses.some(({ envVariables }) => envVariables === null || envVariables === void 0 ? void 0 : envVariables.includes(envVariableName)));
41488
+ }
41489
+
41490
+ /**
41491
+ * Renders the full provider status summary.
41492
+ *
41493
+ * @private function of `$registeredLlmToolsMessage`
41494
+ */
41495
+ function renderRegisteredLlmToolsMessage({ env, llmToolStatuses, usedEnvMessage, isRunningInNode, }) {
41496
+ return spaceTrim$1((block) => `
41497
+
41498
+ ${block(usedEnvMessage)}
41499
+
41500
+ Relevant environment variables:
41501
+ ${block(renderRelevantRegisteredLlmToolsEnvironmentVariables(env, llmToolStatuses))}
41502
+
41503
+ Available LLM providers are:
41504
+ ${block(renderAvailableRegisteredLlmTools(llmToolStatuses, env, isRunningInNode))}
41505
+ `);
41506
+ }
41507
+
41508
+ /**
41509
+ * Pass the `.env` file which was used to configure LLM tools
41510
+ *
41511
+ * Note: `$` is used to indicate that this variable is making side effect
41512
+ *
41513
+ * @private internal log of `$provideLlmToolsConfigurationFromEnv` and `$registeredLlmToolsMessage`
41514
+ */
41515
+ function $setUsedEnvFilename(filepath) {
41516
+ USED_ENV_FILENAME.set(filepath);
41517
+ }
41518
+ /**
41519
+ * Creates a message with all registered LLM tools
41520
+ *
41521
+ * Note: This function is used to create a (error) message when there is no constructor for some LLM provider
41522
+ *
41523
+ * @private internal function of `createLlmToolsFromConfiguration` and `$provideLlmToolsFromEnv`
41524
+ */
41525
+ function $registeredLlmToolsMessage() {
41526
+ const registeredLlmToolsMessageContext = createRegisteredLlmToolsMessageContext();
41527
+ if (registeredLlmToolsMessageContext.llmToolStatuses.length === 0) {
41528
+ return renderNoRegisteredLlmToolsMessage(registeredLlmToolsMessageContext.usedEnvMessage);
41529
+ }
41530
+ return renderRegisteredLlmToolsMessage(registeredLlmToolsMessageContext);
41506
41531
  }
41507
41532
  // TODO: [®] DRY Register logic
41508
41533
  // TODO: [🧠][⚛] Maybe pass env as argument