@promptbook/remote-server 0.113.0-8 → 0.113.0-9

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 (221) hide show
  1. package/esm/index.es.js +1100 -1060
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/src/_packages/types.index.d.ts +2 -2
  4. package/esm/src/avatars/renderAvatarVisualAsciiArt.d.ts +24 -1
  5. package/esm/src/avatars/visuals/octopus3dAvatarVisualShared.d.ts +1 -1
  6. package/esm/src/book-components/BookEditor/BookEditorMonacoUploadPanel.d.ts +1 -1
  7. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/bookEditorMonacoUploadTypes.d.ts +120 -0
  8. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/clearScheduledTimer.d.ts +6 -0
  9. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/enqueueFilesForUpload.d.ts +26 -0
  10. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadEditorSync.d.ts +23 -0
  11. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadItemsState.d.ts +21 -0
  12. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadProgressQueue.d.ts +12 -0
  13. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadQueue.d.ts +27 -0
  14. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads/useCompletedUploadsAutoClear.d.ts +12 -0
  15. package/esm/src/book-components/BookEditor/useBookEditorMonacoUploads.d.ts +5 -58
  16. package/esm/src/book-components/Chat/Chat/ChatImageAttachmentModal.d.ts +25 -0
  17. package/esm/src/book-components/Chat/Chat/ChatInputArea.d.ts +3 -0
  18. package/esm/src/book-components/Chat/Chat/ChatMessageAttachments.d.ts +27 -0
  19. package/esm/src/book-components/Chat/Chat/ChatMessageItem.d.ts +1 -1
  20. package/esm/src/book-components/Chat/Chat/ChatMessageList.d.ts +1 -0
  21. package/esm/src/book-components/Chat/Chat/ChatProps.d.ts +8 -0
  22. package/esm/src/book-components/Chat/Chat/useChatInputAreaComposer.d.ts +12 -0
  23. package/esm/src/book-components/Chat/Chat/useChatInputAreaComposer.draftMessage.test.d.ts +2 -0
  24. package/esm/src/book-components/Chat/utils/isVisibleChatToolCall.d.ts +1 -1
  25. package/esm/src/book-components/Chat/utils/parseMessageButtons.d.ts +16 -2
  26. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/AGENTS_SERVER_BUILD_CACHE_FILENAME.d.ts +6 -0
  27. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/AGENTS_SERVER_BUILD_CACHE_VERSION.d.ts +6 -0
  28. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/AGENTS_SERVER_NEXT_BUILD_ID_FILENAME.d.ts +6 -0
  29. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/AgentsServerBuildCache.d.ts +10 -0
  30. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/AgentsServerBuildCacheOptions.d.ts +10 -0
  31. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/NODE_MODULES_DIRECTORY_NAME.d.ts +6 -0
  32. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/PreparedAgentsServerRuntime.d.ts +18 -0
  33. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerBuildSourceFingerprint.d.ts +6 -0
  34. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerRuntimeEnvironment.d.ts +28 -0
  35. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/ensureAgentsServerBuild.d.ts +19 -0
  36. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/getAgentsServerBuildInputRelativePaths.d.ts +11 -0
  37. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerAppPath.d.ts +6 -0
  38. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerAppPathMaterialized.d.ts +6 -0
  39. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerBuildCacheCurrent.d.ts +7 -0
  40. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerBuildInputTestFile.d.ts +6 -0
  41. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isExcludedAgentsServerBuildInputDirectoryName.d.ts +6 -0
  42. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isExcludedAgentsServerBuildInputPath.d.ts +6 -0
  43. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isExcludedAgentsServerRuntimeSourcePath.d.ts +6 -0
  44. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isFile.d.ts +6 -0
  45. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/isPathInsideNodeModules.d.ts +6 -0
  46. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/normalizeAgentsServerBuildInputPath.d.ts +6 -0
  47. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/prepareAgentsServerRuntime.d.ts +9 -0
  48. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/readAgentsServerBuildCache.d.ts +8 -0
  49. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/resolveAgentsServerAppPath.d.ts +6 -0
  50. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/resolveAgentsServerBuildAppPath.d.ts +9 -0
  51. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/resolveAgentsServerBuildOutputPath.d.ts +7 -0
  52. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/resolveNextCliPath.d.ts +6 -0
  53. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/resolveNodeModulesPath.d.ts +6 -0
  54. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/runNextBuild.d.ts +12 -0
  55. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/shouldCopyAgentsServerRuntimePath.d.ts +6 -0
  56. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/synchronizeMaterializedAgentsServerRuntime.d.ts +11 -0
  57. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/writeAgentsServerBuildCache.d.ts +7 -0
  58. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +8 -109
  59. package/esm/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.d.ts +1 -1
  60. package/esm/src/cli/cli-commands/agents-server/ensureAgentsServerGitignoreFile.d.ts +1 -1
  61. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerChildEnvironment.d.ts +16 -0
  62. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerLogStreams.d.ts +30 -0
  63. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerRuntimePaths.d.ts +19 -0
  64. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerSupervisorState.d.ts +37 -0
  65. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/LocalAgentRunnerLimits.d.ts +9 -0
  66. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/PreparedAgentsServerLaunch.d.ts +13 -0
  67. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/StartAgentsServerOptions.d.ts +24 -0
  68. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/createInternalRouteErrorMessage.d.ts +6 -0
  69. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/createLocalAgentRunOptions.d.ts +9 -0
  70. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/forwardChildOutput.d.ts +13 -0
  71. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/loadAgentsServerProjectEnvironment.d.ts +6 -0
  72. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/prepareAgentsServerLaunch.d.ts +18 -0
  73. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/readInternalRouteErrorDetails.d.ts +6 -0
  74. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/resolveAgentsServerChildHostname.d.ts +7 -0
  75. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/startNextServer.d.ts +20 -0
  76. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/startUserChatJobWorkerPump.d.ts +15 -0
  77. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/stopChildProcess.d.ts +8 -0
  78. package/esm/src/cli/cli-commands/agents-server/startAgentsServer/waitForLocalAgentRunnerLimits.d.ts +16 -0
  79. package/esm/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +3 -30
  80. package/esm/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +1 -1
  81. package/esm/src/collection/agent-collection/CreateAgentInput.d.ts +1 -1
  82. package/esm/src/collection/agent-collection/constructors/agent-collection-in-supabase/prepareAgentSourceForPersistence.d.ts +1 -1
  83. package/esm/src/commitments/META/META.d.ts +2 -2
  84. package/esm/src/commitments/META_AVATAR/META_AVATAR.d.ts +9 -4
  85. package/esm/src/commitments/index.d.ts +1 -1
  86. package/esm/src/conversion/validation/validatePipeline/createPipelineValidationContext.d.ts +16 -0
  87. package/esm/src/conversion/validation/validatePipeline/validatePipelineCollectionsStructure.d.ts +7 -0
  88. package/esm/src/conversion/validation/validatePipeline/validatePipelineDependencyResolution.d.ts +7 -0
  89. package/esm/src/conversion/validation/validatePipeline/validatePipelineMetadata.d.ts +7 -0
  90. package/esm/src/conversion/validation/validatePipeline/validatePipelineParameters.d.ts +7 -0
  91. package/esm/src/conversion/validation/validatePipeline/validatePipelineTasks.d.ts +7 -0
  92. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/RegisteredLlmToolsMessageContext.d.ts +46 -0
  93. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/USED_ENV_FILENAME.d.ts +11 -0
  94. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolConfigurationStatusMessage.d.ts +7 -0
  95. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolEntryKey.d.ts +7 -0
  96. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolInstallationStatusMessage.d.ts +7 -0
  97. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolStatus.d.ts +14 -0
  98. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolsMessageContext.d.ts +7 -0
  99. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/getAvailableRegisteredLlmToolsEnvironmentVariables.d.ts +7 -0
  100. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/getRegisteredLlmToolRegisters.d.ts +7 -0
  101. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/hasRegisteredLlmToolEntry.d.ts +7 -0
  102. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/listRegisteredLlmToolEntries.d.ts +9 -0
  103. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/listRegisteredLlmToolStatuses.d.ts +7 -0
  104. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderAvailableRegisteredLlmTools.d.ts +7 -0
  105. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderNoRegisteredLlmToolsMessage.d.ts +7 -0
  106. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderRegisteredLlmToolsMessage.d.ts +8 -0
  107. package/esm/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderRelevantRegisteredLlmToolsEnvironmentVariables.d.ts +7 -0
  108. package/esm/src/utils/agents/resolveAgentAvatarImageUrl.d.ts +2 -2
  109. package/esm/src/utils/color/Color.d.ts +1 -1
  110. package/esm/src/version.d.ts +1 -1
  111. package/package.json +2 -2
  112. package/umd/index.umd.js +1100 -1060
  113. package/umd/index.umd.js.map +1 -1
  114. package/umd/src/_packages/types.index.d.ts +2 -2
  115. package/umd/src/avatars/renderAvatarVisualAsciiArt.d.ts +24 -1
  116. package/umd/src/avatars/visuals/octopus3dAvatarVisualShared.d.ts +1 -1
  117. package/umd/src/book-components/BookEditor/BookEditorMonacoUploadPanel.d.ts +1 -1
  118. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/bookEditorMonacoUploadTypes.d.ts +120 -0
  119. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/clearScheduledTimer.d.ts +6 -0
  120. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/enqueueFilesForUpload.d.ts +26 -0
  121. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadEditorSync.d.ts +23 -0
  122. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadItemsState.d.ts +21 -0
  123. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadProgressQueue.d.ts +12 -0
  124. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/useBookEditorMonacoUploadQueue.d.ts +27 -0
  125. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads/useCompletedUploadsAutoClear.d.ts +12 -0
  126. package/umd/src/book-components/BookEditor/useBookEditorMonacoUploads.d.ts +5 -58
  127. package/umd/src/book-components/Chat/Chat/ChatImageAttachmentModal.d.ts +25 -0
  128. package/umd/src/book-components/Chat/Chat/ChatInputArea.d.ts +3 -0
  129. package/umd/src/book-components/Chat/Chat/ChatMessageAttachments.d.ts +27 -0
  130. package/umd/src/book-components/Chat/Chat/ChatMessageItem.d.ts +1 -1
  131. package/umd/src/book-components/Chat/Chat/ChatMessageList.d.ts +1 -0
  132. package/umd/src/book-components/Chat/Chat/ChatProps.d.ts +8 -0
  133. package/umd/src/book-components/Chat/Chat/useChatInputAreaComposer.d.ts +12 -0
  134. package/umd/src/book-components/Chat/Chat/useChatInputAreaComposer.draftMessage.test.d.ts +2 -0
  135. package/umd/src/book-components/Chat/utils/isVisibleChatToolCall.d.ts +1 -1
  136. package/umd/src/book-components/Chat/utils/parseMessageButtons.d.ts +16 -2
  137. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/AGENTS_SERVER_BUILD_CACHE_FILENAME.d.ts +6 -0
  138. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/AGENTS_SERVER_BUILD_CACHE_VERSION.d.ts +6 -0
  139. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/AGENTS_SERVER_NEXT_BUILD_ID_FILENAME.d.ts +6 -0
  140. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/AgentsServerBuildCache.d.ts +10 -0
  141. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/AgentsServerBuildCacheOptions.d.ts +10 -0
  142. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/NODE_MODULES_DIRECTORY_NAME.d.ts +6 -0
  143. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/PreparedAgentsServerRuntime.d.ts +18 -0
  144. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerBuildSourceFingerprint.d.ts +6 -0
  145. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerRuntimeEnvironment.d.ts +28 -0
  146. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/ensureAgentsServerBuild.d.ts +19 -0
  147. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/getAgentsServerBuildInputRelativePaths.d.ts +11 -0
  148. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerAppPath.d.ts +6 -0
  149. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerAppPathMaterialized.d.ts +6 -0
  150. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerBuildCacheCurrent.d.ts +7 -0
  151. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isAgentsServerBuildInputTestFile.d.ts +6 -0
  152. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isExcludedAgentsServerBuildInputDirectoryName.d.ts +6 -0
  153. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isExcludedAgentsServerBuildInputPath.d.ts +6 -0
  154. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isExcludedAgentsServerRuntimeSourcePath.d.ts +6 -0
  155. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isFile.d.ts +6 -0
  156. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/isPathInsideNodeModules.d.ts +6 -0
  157. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/normalizeAgentsServerBuildInputPath.d.ts +6 -0
  158. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/prepareAgentsServerRuntime.d.ts +9 -0
  159. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/readAgentsServerBuildCache.d.ts +8 -0
  160. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/resolveAgentsServerAppPath.d.ts +6 -0
  161. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/resolveAgentsServerBuildAppPath.d.ts +9 -0
  162. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/resolveAgentsServerBuildOutputPath.d.ts +7 -0
  163. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/resolveNextCliPath.d.ts +6 -0
  164. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/resolveNodeModulesPath.d.ts +6 -0
  165. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/runNextBuild.d.ts +12 -0
  166. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/shouldCopyAgentsServerRuntimePath.d.ts +6 -0
  167. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/synchronizeMaterializedAgentsServerRuntime.d.ts +11 -0
  168. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/writeAgentsServerBuildCache.d.ts +7 -0
  169. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +8 -109
  170. package/umd/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.d.ts +1 -1
  171. package/umd/src/cli/cli-commands/agents-server/ensureAgentsServerGitignoreFile.d.ts +1 -1
  172. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerChildEnvironment.d.ts +16 -0
  173. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerLogStreams.d.ts +30 -0
  174. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerRuntimePaths.d.ts +19 -0
  175. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/AgentsServerSupervisorState.d.ts +37 -0
  176. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/LocalAgentRunnerLimits.d.ts +9 -0
  177. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/PreparedAgentsServerLaunch.d.ts +13 -0
  178. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/StartAgentsServerOptions.d.ts +24 -0
  179. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/createInternalRouteErrorMessage.d.ts +6 -0
  180. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/createLocalAgentRunOptions.d.ts +9 -0
  181. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/forwardChildOutput.d.ts +13 -0
  182. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/loadAgentsServerProjectEnvironment.d.ts +6 -0
  183. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/prepareAgentsServerLaunch.d.ts +18 -0
  184. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/readInternalRouteErrorDetails.d.ts +6 -0
  185. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/resolveAgentsServerChildHostname.d.ts +7 -0
  186. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/startNextServer.d.ts +20 -0
  187. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/startUserChatJobWorkerPump.d.ts +15 -0
  188. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/stopChildProcess.d.ts +8 -0
  189. package/umd/src/cli/cli-commands/agents-server/startAgentsServer/waitForLocalAgentRunnerLimits.d.ts +16 -0
  190. package/umd/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +3 -30
  191. package/umd/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +1 -1
  192. package/umd/src/collection/agent-collection/CreateAgentInput.d.ts +1 -1
  193. package/umd/src/collection/agent-collection/constructors/agent-collection-in-supabase/prepareAgentSourceForPersistence.d.ts +1 -1
  194. package/umd/src/commitments/META/META.d.ts +2 -2
  195. package/umd/src/commitments/META_AVATAR/META_AVATAR.d.ts +9 -4
  196. package/umd/src/commitments/index.d.ts +1 -1
  197. package/umd/src/conversion/validation/validatePipeline/createPipelineValidationContext.d.ts +16 -0
  198. package/umd/src/conversion/validation/validatePipeline/validatePipelineCollectionsStructure.d.ts +7 -0
  199. package/umd/src/conversion/validation/validatePipeline/validatePipelineDependencyResolution.d.ts +7 -0
  200. package/umd/src/conversion/validation/validatePipeline/validatePipelineMetadata.d.ts +7 -0
  201. package/umd/src/conversion/validation/validatePipeline/validatePipelineParameters.d.ts +7 -0
  202. package/umd/src/conversion/validation/validatePipeline/validatePipelineTasks.d.ts +7 -0
  203. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/RegisteredLlmToolsMessageContext.d.ts +46 -0
  204. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/USED_ENV_FILENAME.d.ts +11 -0
  205. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolConfigurationStatusMessage.d.ts +7 -0
  206. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolEntryKey.d.ts +7 -0
  207. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolInstallationStatusMessage.d.ts +7 -0
  208. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolStatus.d.ts +14 -0
  209. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/createRegisteredLlmToolsMessageContext.d.ts +7 -0
  210. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/getAvailableRegisteredLlmToolsEnvironmentVariables.d.ts +7 -0
  211. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/getRegisteredLlmToolRegisters.d.ts +7 -0
  212. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/hasRegisteredLlmToolEntry.d.ts +7 -0
  213. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/listRegisteredLlmToolEntries.d.ts +9 -0
  214. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/listRegisteredLlmToolStatuses.d.ts +7 -0
  215. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderAvailableRegisteredLlmTools.d.ts +7 -0
  216. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderNoRegisteredLlmToolsMessage.d.ts +7 -0
  217. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderRegisteredLlmToolsMessage.d.ts +8 -0
  218. package/umd/src/llm-providers/_common/register/$registeredLlmToolsMessage/renderRelevantRegisteredLlmToolsEnvironmentVariables.d.ts +7 -0
  219. package/umd/src/utils/agents/resolveAgentAvatarImageUrl.d.ts +2 -2
  220. package/umd/src/utils/color/Color.d.ts +1 -1
  221. package/umd/src/version.d.ts +1 -1
package/esm/index.es.js CHANGED
@@ -40,7 +40,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
40
40
  * @generated
41
41
  * @see https://github.com/webgptorg/promptbook
42
42
  */
43
- const PROMPTBOOK_ENGINE_VERSION = '0.113.0-8';
43
+ const PROMPTBOOK_ENGINE_VERSION = '0.113.0-9';
44
44
  /**
45
45
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
46
46
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -103,6 +103,127 @@ function take(initialValue) {
103
103
  });
104
104
  }
105
105
 
106
+ /**
107
+ * Validates that a channel value is a valid number within the range of 0 to 255.
108
+ * Throws an error if the value is not valid.
109
+ *
110
+ * @param channelName - The name of the channel being validated.
111
+ * @param value - The value of the channel to validate.
112
+ * @throws Will throw an error if the value is not a valid channel number.
113
+ *
114
+ * @private util of `@promptbook/color`
115
+ */
116
+ function checkChannelValue(channelName, value) {
117
+ if (typeof value !== 'number') {
118
+ throw new Error(`${channelName} channel value is not number but ${typeof value}`);
119
+ }
120
+ if (isNaN(value)) {
121
+ throw new Error(`${channelName} channel value is NaN`);
122
+ }
123
+ if (Math.round(value) !== value) {
124
+ throw new Error(`${channelName} channel is not whole number, it is ${value}`);
125
+ }
126
+ if (value < 0) {
127
+ throw new Error(`${channelName} channel is lower than 0, it is ${value}`);
128
+ }
129
+ if (value > 255) {
130
+ throw new Error(`${channelName} channel is greater than 255, it is ${value}`);
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Shared immutable channel storage and serialization helpers for `Color`.
136
+ *
137
+ * @private base class of Color
138
+ */
139
+ class ColorValue {
140
+ constructor(red, green, blue, alpha = 255) {
141
+ this.red = red;
142
+ this.green = green;
143
+ this.blue = blue;
144
+ this.alpha = alpha;
145
+ checkChannelValue('Red', red);
146
+ checkChannelValue('Green', green);
147
+ checkChannelValue('Blue', blue);
148
+ checkChannelValue('Alpha', alpha);
149
+ }
150
+ /**
151
+ * Shortcut for `red` property
152
+ * Number from 0 to 255
153
+ * @alias red
154
+ */
155
+ get r() {
156
+ return this.red;
157
+ }
158
+ /**
159
+ * Shortcut for `green` property
160
+ * Number from 0 to 255
161
+ * @alias green
162
+ */
163
+ get g() {
164
+ return this.green;
165
+ }
166
+ /**
167
+ * Shortcut for `blue` property
168
+ * Number from 0 to 255
169
+ * @alias blue
170
+ */
171
+ get b() {
172
+ return this.blue;
173
+ }
174
+ /**
175
+ * Shortcut for `alpha` property
176
+ * Number from 0 (transparent) to 255 (opaque)
177
+ * @alias alpha
178
+ */
179
+ get a() {
180
+ return this.alpha;
181
+ }
182
+ /**
183
+ * Shortcut for `alpha` property
184
+ * Number from 0 (transparent) to 255 (opaque)
185
+ * @alias alpha
186
+ */
187
+ get opacity() {
188
+ return this.alpha;
189
+ }
190
+ /**
191
+ * Shortcut for 1-`alpha` property
192
+ */
193
+ get transparency() {
194
+ return 255 - this.alpha;
195
+ }
196
+ clone() {
197
+ return take(this.createColor(this.red, this.green, this.blue, this.alpha));
198
+ }
199
+ toString() {
200
+ return this.toHex();
201
+ }
202
+ toHex() {
203
+ if (this.alpha === 255) {
204
+ return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
205
+ .toString(16)
206
+ .padStart(2, '0')}`;
207
+ }
208
+ else {
209
+ return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
210
+ .toString(16)
211
+ .padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
212
+ }
213
+ }
214
+ toRgb() {
215
+ if (this.alpha === 255) {
216
+ return `rgb(${this.red}, ${this.green}, ${this.blue})`;
217
+ }
218
+ else {
219
+ return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
220
+ }
221
+ }
222
+ toHsl() {
223
+ throw new Error(`Getting HSL is not implemented`);
224
+ }
225
+ }
226
+
106
227
  /**
107
228
  * 🎨 List of all 140 color names which are supported by CSS
108
229
  *
@@ -262,127 +383,6 @@ const CSS_COLORS = {
262
383
  };
263
384
  // Note: [💞] Ignore a discrepancy between file name and entity name
264
385
 
265
- /**
266
- * Validates that a channel value is a valid number within the range of 0 to 255.
267
- * Throws an error if the value is not valid.
268
- *
269
- * @param channelName - The name of the channel being validated.
270
- * @param value - The value of the channel to validate.
271
- * @throws Will throw an error if the value is not a valid channel number.
272
- *
273
- * @private util of `@promptbook/color`
274
- */
275
- function checkChannelValue(channelName, value) {
276
- if (typeof value !== 'number') {
277
- throw new Error(`${channelName} channel value is not number but ${typeof value}`);
278
- }
279
- if (isNaN(value)) {
280
- throw new Error(`${channelName} channel value is NaN`);
281
- }
282
- if (Math.round(value) !== value) {
283
- throw new Error(`${channelName} channel is not whole number, it is ${value}`);
284
- }
285
- if (value < 0) {
286
- throw new Error(`${channelName} channel is lower than 0, it is ${value}`);
287
- }
288
- if (value > 255) {
289
- throw new Error(`${channelName} channel is greater than 255, it is ${value}`);
290
- }
291
- }
292
-
293
- /**
294
- * Shared immutable channel storage and serialization helpers for `Color`.
295
- *
296
- * @private base class of Color
297
- */
298
- class ColorValue {
299
- constructor(red, green, blue, alpha = 255) {
300
- this.red = red;
301
- this.green = green;
302
- this.blue = blue;
303
- this.alpha = alpha;
304
- checkChannelValue('Red', red);
305
- checkChannelValue('Green', green);
306
- checkChannelValue('Blue', blue);
307
- checkChannelValue('Alpha', alpha);
308
- }
309
- /**
310
- * Shortcut for `red` property
311
- * Number from 0 to 255
312
- * @alias red
313
- */
314
- get r() {
315
- return this.red;
316
- }
317
- /**
318
- * Shortcut for `green` property
319
- * Number from 0 to 255
320
- * @alias green
321
- */
322
- get g() {
323
- return this.green;
324
- }
325
- /**
326
- * Shortcut for `blue` property
327
- * Number from 0 to 255
328
- * @alias blue
329
- */
330
- get b() {
331
- return this.blue;
332
- }
333
- /**
334
- * Shortcut for `alpha` property
335
- * Number from 0 (transparent) to 255 (opaque)
336
- * @alias alpha
337
- */
338
- get a() {
339
- return this.alpha;
340
- }
341
- /**
342
- * Shortcut for `alpha` property
343
- * Number from 0 (transparent) to 255 (opaque)
344
- * @alias alpha
345
- */
346
- get opacity() {
347
- return this.alpha;
348
- }
349
- /**
350
- * Shortcut for 1-`alpha` property
351
- */
352
- get transparency() {
353
- return 255 - this.alpha;
354
- }
355
- clone() {
356
- return take(this.createColor(this.red, this.green, this.blue, this.alpha));
357
- }
358
- toString() {
359
- return this.toHex();
360
- }
361
- toHex() {
362
- if (this.alpha === 255) {
363
- return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
364
- .toString(16)
365
- .padStart(2, '0')}`;
366
- }
367
- else {
368
- return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
369
- .toString(16)
370
- .padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
371
- }
372
- }
373
- toRgb() {
374
- if (this.alpha === 255) {
375
- return `rgb(${this.red}, ${this.green}, ${this.blue})`;
376
- }
377
- else {
378
- return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
379
- }
380
- }
381
- toHsl() {
382
- throw new Error(`Getting HSL is not implemented`);
383
- }
384
- }
385
-
386
386
  /**
387
387
  * Checks if the given value is a valid hex color string
388
388
  *
@@ -2150,6 +2150,82 @@ function resolveBookPipelineUrl(request, pipelines) {
2150
2150
  return pipelines.find((pipelineUrl) => pipelineUrl.endsWith(request.originalUrl)) || fullUrl;
2151
2151
  }
2152
2152
 
2153
+ /**
2154
+ * Creates the shared validation context for one pipeline.
2155
+ *
2156
+ * @private function of `validatePipeline`
2157
+ */
2158
+ function createPipelineValidationContext(pipeline) {
2159
+ return {
2160
+ pipeline,
2161
+ pipelineIdentification: getPipelineIdentification(pipeline),
2162
+ };
2163
+ }
2164
+ /**
2165
+ * Builds a short file/url identification block for validation errors.
2166
+ *
2167
+ * @private internal utility of `validatePipeline`
2168
+ */
2169
+ function getPipelineIdentification(pipeline) {
2170
+ // Note: This is a 😐 implementation of [🚞]
2171
+ const pipelineIdentificationParts = [];
2172
+ if (pipeline.sourceFile !== undefined) {
2173
+ pipelineIdentificationParts.push(`File: ${pipeline.sourceFile}`);
2174
+ }
2175
+ if (pipeline.pipelineUrl !== undefined) {
2176
+ pipelineIdentificationParts.push(`Url: ${pipeline.pipelineUrl}`);
2177
+ }
2178
+ return pipelineIdentificationParts.join('\n');
2179
+ }
2180
+
2181
+ /**
2182
+ * Validates that the expected top-level collections have array structure.
2183
+ *
2184
+ * @private function of `validatePipeline`
2185
+ */
2186
+ function validatePipelineCollectionsStructure({ pipeline, pipelineIdentification, }) {
2187
+ validatePipelineParametersCollection(pipeline, pipelineIdentification);
2188
+ validatePipelineTasksCollection(pipeline, pipelineIdentification);
2189
+ }
2190
+ /**
2191
+ * Validates that `pipeline.parameters` is an array.
2192
+ *
2193
+ * @private internal utility of `validatePipelineCollectionsStructure`
2194
+ */
2195
+ function validatePipelineParametersCollection(pipeline, pipelineIdentification) {
2196
+ // TODO: [🧠] Maybe do here some proper JSON-schema / ZOD checking
2197
+ if (Array.isArray(pipeline.parameters)) {
2198
+ return;
2199
+ }
2200
+ // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
2201
+ throw new ParseError(spaceTrim$1((block) => `
2202
+ Pipeline is valid JSON but with wrong structure
2203
+
2204
+ \`PipelineJson.parameters\` expected to be an array, but got ${typeof pipeline.parameters}
2205
+
2206
+ ${block(pipelineIdentification)}
2207
+ `));
2208
+ }
2209
+ /**
2210
+ * Validates that `pipeline.tasks` is an array.
2211
+ *
2212
+ * @private internal utility of `validatePipelineCollectionsStructure`
2213
+ */
2214
+ function validatePipelineTasksCollection(pipeline, pipelineIdentification) {
2215
+ // TODO: [🧠] Maybe do here some proper JSON-schema / ZOD checking
2216
+ if (Array.isArray(pipeline.tasks)) {
2217
+ return;
2218
+ }
2219
+ // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
2220
+ throw new ParseError(spaceTrim$1((block) => `
2221
+ Pipeline is valid JSON but with wrong structure
2222
+
2223
+ \`PipelineJson.tasks\` expected to be an array, but got ${typeof pipeline.tasks}
2224
+
2225
+ ${block(pipelineIdentification)}
2226
+ `));
2227
+ }
2228
+
2153
2229
  /**
2154
2230
  * Orders JSON object by keys
2155
2231
  *
@@ -2563,6 +2639,140 @@ const LIMITS = {
2563
2639
  };
2564
2640
  // Note: [💞] Ignore a discrepancy between file name and entity name
2565
2641
 
2642
+ /**
2643
+ * Validates that task dependencies can be resolved without cycles or missing definitions.
2644
+ *
2645
+ * @private function of `validatePipeline`
2646
+ */
2647
+ function validatePipelineDependencyResolution({ pipeline, pipelineIdentification, }) {
2648
+ let dependencyResolutionState = createInitialDependencyResolutionState(pipeline);
2649
+ let loopLimit = LOOP_LIMIT;
2650
+ while (hasUnresolvedTasks(dependencyResolutionState)) {
2651
+ if (loopLimit-- < 0) {
2652
+ throw createDependencyResolutionLoopLimitError(pipelineIdentification);
2653
+ }
2654
+ dependencyResolutionState = resolveNextDependencyResolutionState(dependencyResolutionState, pipelineIdentification);
2655
+ }
2656
+ }
2657
+ /**
2658
+ * Collects the parameter names that are already resolvable before dependency traversal starts.
2659
+ *
2660
+ * @private internal utility of `validatePipelineDependencyResolution`
2661
+ */
2662
+ function createInitialDependencyResolutionState(pipeline) {
2663
+ return {
2664
+ resolvedParameterNames: createInitiallyResolvedParameterNames(pipeline),
2665
+ unresolvedTasks: [...pipeline.tasks],
2666
+ };
2667
+ }
2668
+ /**
2669
+ * Checks whether dependency resolution still has tasks left to process.
2670
+ *
2671
+ * @private internal utility of `validatePipelineDependencyResolution`
2672
+ */
2673
+ function hasUnresolvedTasks({ unresolvedTasks }) {
2674
+ return unresolvedTasks.length > 0;
2675
+ }
2676
+ /**
2677
+ * Resolves the next batch of currently satisfiable tasks.
2678
+ *
2679
+ * @private internal utility of `validatePipelineDependencyResolution`
2680
+ */
2681
+ function resolveNextDependencyResolutionState(dependencyResolutionState, pipelineIdentification) {
2682
+ const currentlyResolvedTasks = getCurrentlyResolvedTasks(dependencyResolutionState.unresolvedTasks, dependencyResolutionState.resolvedParameterNames);
2683
+ if (currentlyResolvedTasks.length === 0) {
2684
+ throw createUnresolvedTasksError(dependencyResolutionState.unresolvedTasks, dependencyResolutionState.resolvedParameterNames, pipelineIdentification);
2685
+ }
2686
+ return {
2687
+ resolvedParameterNames: appendResolvedTaskParameterNames(dependencyResolutionState.resolvedParameterNames, currentlyResolvedTasks),
2688
+ unresolvedTasks: dependencyResolutionState.unresolvedTasks.filter((task) => !currentlyResolvedTasks.includes(task)),
2689
+ };
2690
+ }
2691
+ /**
2692
+ * Collects the parameter names that are already resolvable before dependency traversal starts.
2693
+ *
2694
+ * @private internal utility of `validatePipelineDependencyResolution`
2695
+ */
2696
+ function createInitiallyResolvedParameterNames(pipeline) {
2697
+ let resolvedParameterNames = pipeline.parameters
2698
+ .filter(({ isInput }) => isInput)
2699
+ .map(({ name }) => name);
2700
+ for (const reservedParameterName of RESERVED_PARAMETER_NAMES) {
2701
+ resolvedParameterNames = [...resolvedParameterNames, reservedParameterName];
2702
+ }
2703
+ return resolvedParameterNames;
2704
+ }
2705
+ /**
2706
+ * Adds newly resolved task outputs to the resolved parameter list.
2707
+ *
2708
+ * @private internal utility of `validatePipelineDependencyResolution`
2709
+ */
2710
+ function appendResolvedTaskParameterNames(resolvedParameterNames, currentlyResolvedTasks) {
2711
+ return [
2712
+ ...resolvedParameterNames,
2713
+ ...currentlyResolvedTasks.map(({ resultingParameterName }) => resultingParameterName),
2714
+ ];
2715
+ }
2716
+ /**
2717
+ * Selects tasks whose dependencies are already resolved.
2718
+ *
2719
+ * @private internal utility of `validatePipelineDependencyResolution`
2720
+ */
2721
+ function getCurrentlyResolvedTasks(unresolvedTasks, resolvedParameterNames) {
2722
+ return unresolvedTasks.filter((task) => task.dependentParameterNames.every((name) => resolvedParameterNames.includes(name)));
2723
+ }
2724
+ /**
2725
+ * Creates the unexpected loop-limit error for dependency resolution.
2726
+ *
2727
+ * @private internal utility of `validatePipelineDependencyResolution`
2728
+ */
2729
+ function createDependencyResolutionLoopLimitError(pipelineIdentification) {
2730
+ // Note: Really UnexpectedError not LimitReachedError - this should not happen and be caught below
2731
+ return new UnexpectedError(spaceTrim$1((block) => `
2732
+ Loop limit reached during detection of circular dependencies in \`validatePipeline\`
2733
+
2734
+ ${block(pipelineIdentification)}
2735
+ `));
2736
+ }
2737
+ /**
2738
+ * Creates the detailed error for unresolved or circular task dependencies.
2739
+ *
2740
+ * @private internal utility of `validatePipelineDependencyResolution`
2741
+ */
2742
+ function createUnresolvedTasksError(unresolvedTasks, resolvedParameterNames, pipelineIdentification) {
2743
+ return new PipelineLogicError(
2744
+ // TODO: [🐎] DRY
2745
+ spaceTrim$1((block) => `
2746
+
2747
+ Can not resolve some parameters:
2748
+ Either you are using a parameter that is not defined, or there are some circular dependencies.
2749
+
2750
+ ${block(pipelineIdentification)}
2751
+
2752
+ **Can not resolve:**
2753
+ ${block(unresolvedTasks
2754
+ .map(({ resultingParameterName, dependentParameterNames }) => `- Parameter \`{${resultingParameterName}}\` which depends on ${dependentParameterNames
2755
+ .map((dependentParameterName) => `\`{${dependentParameterName}}\``)
2756
+ .join(' and ')}`)
2757
+ .join('\n'))}
2758
+
2759
+ **Resolved:**
2760
+ ${block(resolvedParameterNames
2761
+ .filter((name) => !RESERVED_PARAMETER_NAMES.includes(name))
2762
+ .map((name) => `- Parameter \`{${name}}\``)
2763
+ .join('\n'))}
2764
+
2765
+
2766
+ **Reserved (which are available):**
2767
+ ${block(resolvedParameterNames
2768
+ .filter((name) => RESERVED_PARAMETER_NAMES.includes(name))
2769
+ .map((name) => `- Parameter \`{${name}}\``)
2770
+ .join('\n'))}
2771
+
2772
+
2773
+ `));
2774
+ }
2775
+
2566
2776
  /**
2567
2777
  * Tests if given string is valid semantic version
2568
2778
  *
@@ -2668,168 +2878,19 @@ function isValidPipelineUrl(url) {
2668
2878
  }
2669
2879
  // TODO: [🐠] Maybe more info why the URL is invalid
2670
2880
 
2671
- /**
2672
- * Validates PipelineJson if it is logically valid
2673
- *
2674
- * It checks:
2675
- * - if it has correct parameters dependency
2676
- *
2677
- * It does NOT check:
2678
- * - if it is valid json
2679
- * - if it is meaningful
2680
- *
2681
- * Note: [🔂] This function is idempotent.
2682
- *
2683
- * @param pipeline valid or invalid PipelineJson
2684
- * @returns the same pipeline if it is logically valid
2685
- * @throws {PipelineLogicError} on logical error in the pipeline
2686
- *
2687
- * @public exported from `@promptbook/core`
2688
- */
2689
- function validatePipeline(pipeline) {
2690
- if (IS_PIPELINE_LOGIC_VALIDATED) {
2691
- validatePipeline_InnerFunction(pipeline);
2692
- }
2693
- else {
2694
- try {
2695
- validatePipeline_InnerFunction(pipeline);
2696
- }
2697
- catch (error) {
2698
- if (!(error instanceof PipelineLogicError)) {
2699
- throw error;
2700
- }
2701
- console.error(spaceTrim$1((block) => `
2702
- Pipeline is not valid but logic errors are temporarily disabled via \`IS_PIPELINE_LOGIC_VALIDATED\`
2703
-
2704
- ${block(error.message)}
2705
- `));
2706
- }
2707
- }
2708
- return pipeline;
2709
- }
2710
- /**
2711
- * Validates pipeline inner function.
2712
- *
2713
- * @private internal function for `validatePipeline`
2714
- */
2715
- function validatePipeline_InnerFunction(pipeline) {
2716
- // TODO: [🧠] Maybe test if promptbook is a promise and make specific error case for that
2717
- const context = createPipelineValidationContext(pipeline);
2718
- validatePipelineMetadata(context);
2719
- validatePipelineCollectionsStructure(context);
2720
- validatePipelineParameters(context);
2721
- validatePipelineTasks(context);
2722
- validatePipelineDependencyResolution(context);
2723
- // Note: Check that formfactor is corresponding to the pipeline interface
2724
- // TODO: !!6 Implement this
2725
- // pipeline.formfactorName
2726
- }
2727
- /**
2728
- * Creates the shared validation context for one pipeline.
2729
- *
2730
- * @private internal utility of `validatePipeline`
2731
- */
2732
- function createPipelineValidationContext(pipeline) {
2733
- return {
2734
- pipeline,
2735
- pipelineIdentification: getPipelineIdentification(pipeline),
2736
- };
2737
- }
2738
- /**
2739
- * Builds a short file/url identification block for validation errors.
2740
- *
2741
- * @private internal utility of `validatePipeline`
2742
- */
2743
- function getPipelineIdentification(pipeline) {
2744
- // Note: This is a 😐 implementation of [🚞]
2745
- const pipelineIdentificationParts = [];
2746
- if (pipeline.sourceFile !== undefined) {
2747
- pipelineIdentificationParts.push(`File: ${pipeline.sourceFile}`);
2748
- }
2749
- if (pipeline.pipelineUrl !== undefined) {
2750
- pipelineIdentificationParts.push(`Url: ${pipeline.pipelineUrl}`);
2751
- }
2752
- return pipelineIdentificationParts.join('\n');
2753
- }
2754
2881
  /**
2755
2882
  * Validates pipeline-level metadata fields.
2756
2883
  *
2757
- * @private internal step of `validatePipeline`
2884
+ * @private function of `validatePipeline`
2758
2885
  */
2759
2886
  function validatePipelineMetadata({ pipeline, pipelineIdentification }) {
2760
2887
  validatePipelineUrl(pipeline, pipelineIdentification);
2761
2888
  validatePipelineBookVersion(pipeline, pipelineIdentification);
2762
2889
  }
2763
- /**
2764
- * Validates that the expected top-level collections have array structure.
2765
- *
2766
- * @private internal step of `validatePipeline`
2767
- */
2768
- function validatePipelineCollectionsStructure({ pipeline, pipelineIdentification }) {
2769
- validatePipelineParametersCollection(pipeline, pipelineIdentification);
2770
- validatePipelineTasksCollection(pipeline, pipelineIdentification);
2771
- }
2772
- /**
2773
- * Validates all pipeline parameter declarations.
2774
- *
2775
- * @private internal step of `validatePipeline`
2776
- */
2777
- function validatePipelineParameters({ pipeline, pipelineIdentification }) {
2778
- for (const parameter of pipeline.parameters) {
2779
- validatePipelineParameter(parameter, pipeline, pipelineIdentification);
2780
- }
2781
- }
2782
- /**
2783
- * Validates all pipeline tasks and their per-task invariants.
2784
- *
2785
- * @private internal step of `validatePipeline`
2786
- */
2787
- function validatePipelineTasks({ pipeline, pipelineIdentification }) {
2788
- // Note: All input parameters are defined - so that they can be used as result of some task
2789
- const definedParameters = createInitiallyDefinedParameters(pipeline);
2790
- for (const task of pipeline.tasks) {
2791
- validatePipelineTask(task, definedParameters, pipelineIdentification);
2792
- }
2793
- }
2794
- /**
2795
- * Validates that task dependencies can be resolved without cycles or missing definitions.
2796
- *
2797
- * @private internal step of `validatePipeline`
2798
- */
2799
- function validatePipelineDependencyResolution({ pipeline, pipelineIdentification }) {
2800
- let dependencyResolutionState = createInitialDependencyResolutionState(pipeline);
2801
- let loopLimit = LOOP_LIMIT;
2802
- while (hasUnresolvedTasks(dependencyResolutionState)) {
2803
- if (loopLimit-- < 0) {
2804
- throw createDependencyResolutionLoopLimitError(pipelineIdentification);
2805
- }
2806
- dependencyResolutionState = resolveNextDependencyResolutionState(dependencyResolutionState, pipelineIdentification);
2807
- }
2808
- }
2809
- /**
2810
- * Validates one pipeline parameter declaration.
2811
- *
2812
- * @private internal step of `validatePipeline`
2813
- */
2814
- function validatePipelineParameter(parameter, pipeline, pipelineIdentification) {
2815
- validateParameterDirection(parameter, pipelineIdentification);
2816
- validateParameterUsage(parameter, pipeline, pipelineIdentification);
2817
- validateParameterDefinition(parameter, pipeline, pipelineIdentification);
2818
- }
2819
- /**
2820
- * Validates one pipeline task and its invariants.
2821
- *
2822
- * @private internal step of `validatePipeline`
2823
- */
2824
- function validatePipelineTask(task, definedParameters, pipelineIdentification) {
2825
- validateTaskResultingParameter(task, definedParameters, pipelineIdentification);
2826
- validateTaskJokers(task, pipelineIdentification);
2827
- validateTaskExpectations(task, pipelineIdentification);
2828
- }
2829
2890
  /**
2830
2891
  * Validates the pipeline URL, when present.
2831
2892
  *
2832
- * @private internal utility of `validatePipeline`
2893
+ * @private internal utility of `validatePipelineMetadata`
2833
2894
  */
2834
2895
  function validatePipelineUrl(pipeline, pipelineIdentification) {
2835
2896
  if (pipeline.pipelineUrl === undefined || isValidPipelineUrl(pipeline.pipelineUrl)) {
@@ -2845,7 +2906,7 @@ function validatePipelineUrl(pipeline, pipelineIdentification) {
2845
2906
  /**
2846
2907
  * Validates the Promptbook version, when present.
2847
2908
  *
2848
- * @private internal utility of `validatePipeline`
2909
+ * @private internal utility of `validatePipelineMetadata`
2849
2910
  */
2850
2911
  function validatePipelineBookVersion(pipeline, pipelineIdentification) {
2851
2912
  if (pipeline.bookVersion === undefined || isValidPromptbookVersion(pipeline.bookVersion)) {
@@ -2858,48 +2919,31 @@ function validatePipelineBookVersion(pipeline, pipelineIdentification) {
2858
2919
  ${block(pipelineIdentification)}
2859
2920
  `));
2860
2921
  }
2922
+
2861
2923
  /**
2862
- * Validates that `pipeline.parameters` is an array.
2924
+ * Validates all pipeline parameter declarations.
2863
2925
  *
2864
- * @private internal utility of `validatePipeline`
2926
+ * @private function of `validatePipeline`
2865
2927
  */
2866
- function validatePipelineParametersCollection(pipeline, pipelineIdentification) {
2867
- // TODO: [🧠] Maybe do here some proper JSON-schema / ZOD checking
2868
- if (Array.isArray(pipeline.parameters)) {
2869
- return;
2928
+ function validatePipelineParameters({ pipeline, pipelineIdentification }) {
2929
+ for (const parameter of pipeline.parameters) {
2930
+ validatePipelineParameter(parameter, pipeline, pipelineIdentification);
2870
2931
  }
2871
- // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
2872
- throw new ParseError(spaceTrim$1((block) => `
2873
- Pipeline is valid JSON but with wrong structure
2874
-
2875
- \`PipelineJson.parameters\` expected to be an array, but got ${typeof pipeline.parameters}
2876
-
2877
- ${block(pipelineIdentification)}
2878
- `));
2879
2932
  }
2880
2933
  /**
2881
- * Validates that `pipeline.tasks` is an array.
2934
+ * Validates one pipeline parameter declaration.
2882
2935
  *
2883
- * @private internal utility of `validatePipeline`
2936
+ * @private internal utility of `validatePipelineParameters`
2884
2937
  */
2885
- function validatePipelineTasksCollection(pipeline, pipelineIdentification) {
2886
- // TODO: [🧠] Maybe do here some proper JSON-schema / ZOD checking
2887
- if (Array.isArray(pipeline.tasks)) {
2888
- return;
2889
- }
2890
- // TODO: [🧠] what is the correct error tp throw - maybe PromptbookSchemaError
2891
- throw new ParseError(spaceTrim$1((block) => `
2892
- Pipeline is valid JSON but with wrong structure
2893
-
2894
- \`PipelineJson.tasks\` expected to be an array, but got ${typeof pipeline.tasks}
2895
-
2896
- ${block(pipelineIdentification)}
2897
- `));
2938
+ function validatePipelineParameter(parameter, pipeline, pipelineIdentification) {
2939
+ validateParameterDirection(parameter, pipelineIdentification);
2940
+ validateParameterUsage(parameter, pipeline, pipelineIdentification);
2941
+ validateParameterDefinition(parameter, pipeline, pipelineIdentification);
2898
2942
  }
2899
2943
  /**
2900
2944
  * Validates that one parameter does not declare incompatible directions.
2901
2945
  *
2902
- * @private internal utility of `validatePipeline`
2946
+ * @private internal utility of `validatePipelineParameters`
2903
2947
  */
2904
2948
  function validateParameterDirection(parameter, pipelineIdentification) {
2905
2949
  if (!parameter.isInput || !parameter.isOutput) {
@@ -2916,7 +2960,7 @@ function validateParameterDirection(parameter, pipelineIdentification) {
2916
2960
  /**
2917
2961
  * Validates that one intermediate parameter is actually consumed by at least one task.
2918
2962
  *
2919
- * @private internal utility of `validatePipeline`
2963
+ * @private internal utility of `validatePipelineParameters`
2920
2964
  */
2921
2965
  function validateParameterUsage(parameter, pipeline, pipelineIdentification) {
2922
2966
  if (parameter.isInput || parameter.isOutput || isParameterUsedByAnyTask(parameter, pipeline.tasks)) {
@@ -2935,7 +2979,7 @@ function validateParameterUsage(parameter, pipeline, pipelineIdentification) {
2935
2979
  /**
2936
2980
  * Validates that one non-input parameter is produced by at least one task.
2937
2981
  *
2938
- * @private internal utility of `validatePipeline`
2982
+ * @private internal utility of `validatePipelineParameters`
2939
2983
  */
2940
2984
  function validateParameterDefinition(parameter, pipeline, pipelineIdentification) {
2941
2985
  if (parameter.isInput || isParameterDefinedByAnyTask(parameter, pipeline.tasks)) {
@@ -2954,7 +2998,7 @@ function validateParameterDefinition(parameter, pipeline, pipelineIdentification
2954
2998
  /**
2955
2999
  * Checks whether one parameter is consumed by at least one task dependency list.
2956
3000
  *
2957
- * @private internal utility of `validatePipeline`
3001
+ * @private internal utility of `validatePipelineParameters`
2958
3002
  */
2959
3003
  function isParameterUsedByAnyTask(parameter, tasks) {
2960
3004
  return tasks.some((task) => task.dependentParameterNames.includes(parameter.name));
@@ -2962,23 +3006,46 @@ function isParameterUsedByAnyTask(parameter, tasks) {
2962
3006
  /**
2963
3007
  * Checks whether one parameter is produced by at least one task.
2964
3008
  *
2965
- * @private internal utility of `validatePipeline`
3009
+ * @private internal utility of `validatePipelineParameters`
2966
3010
  */
2967
3011
  function isParameterDefinedByAnyTask(parameter, tasks) {
2968
3012
  return tasks.some((task) => task.resultingParameterName === parameter.name);
2969
3013
  }
3014
+
3015
+ /**
3016
+ * Validates all pipeline tasks and their per-task invariants.
3017
+ *
3018
+ * @private function of `validatePipeline`
3019
+ */
3020
+ function validatePipelineTasks({ pipeline, pipelineIdentification }) {
3021
+ // Note: All input parameters are defined - so that they can be used as result of some task
3022
+ const definedParameters = createInitiallyDefinedParameters(pipeline);
3023
+ for (const task of pipeline.tasks) {
3024
+ validatePipelineTask(task, definedParameters, pipelineIdentification);
3025
+ }
3026
+ }
2970
3027
  /**
2971
3028
  * Collects the parameter names that are already defined before task validation starts.
2972
3029
  *
2973
- * @private internal utility of `validatePipeline`
3030
+ * @private internal utility of `validatePipelineTasks`
2974
3031
  */
2975
3032
  function createInitiallyDefinedParameters(pipeline) {
2976
3033
  return new Set(pipeline.parameters.filter(({ isInput }) => isInput).map(({ name }) => name));
2977
3034
  }
3035
+ /**
3036
+ * Validates one pipeline task and its invariants.
3037
+ *
3038
+ * @private internal utility of `validatePipelineTasks`
3039
+ */
3040
+ function validatePipelineTask(task, definedParameters, pipelineIdentification) {
3041
+ validateTaskResultingParameter(task, definedParameters, pipelineIdentification);
3042
+ validateTaskJokers(task, pipelineIdentification);
3043
+ validateTaskExpectations(task, pipelineIdentification);
3044
+ }
2978
3045
  /**
2979
3046
  * Validates one task result parameter declaration and marks it as defined.
2980
3047
  *
2981
- * @private internal utility of `validatePipeline`
3048
+ * @private internal utility of `validatePipelineTasks`
2982
3049
  */
2983
3050
  function validateTaskResultingParameter(task, definedParameters, pipelineIdentification) {
2984
3051
  if (definedParameters.has(task.resultingParameterName)) {
@@ -3000,7 +3067,7 @@ function validateTaskResultingParameter(task, definedParameters, pipelineIdentif
3000
3067
  /**
3001
3068
  * Validates joker parameters for one task.
3002
3069
  *
3003
- * @private internal utility of `validatePipeline`
3070
+ * @private internal utility of `validatePipelineTasks`
3004
3071
  */
3005
3072
  function validateTaskJokers(task, pipelineIdentification) {
3006
3073
  if (!hasTaskJokers(task)) {
@@ -3012,7 +3079,7 @@ function validateTaskJokers(task, pipelineIdentification) {
3012
3079
  /**
3013
3080
  * Checks whether one task declares any joker parameters.
3014
3081
  *
3015
- * @private internal utility of `validatePipeline`
3082
+ * @private internal utility of `validatePipelineTasks`
3016
3083
  */
3017
3084
  function hasTaskJokers(task) {
3018
3085
  return !!task.jokerParameterNames && task.jokerParameterNames.length > 0;
@@ -3020,7 +3087,7 @@ function hasTaskJokers(task) {
3020
3087
  /**
3021
3088
  * Validates that a task has the required supporting features when using jokers.
3022
3089
  *
3023
- * @private internal utility of `validatePipeline`
3090
+ * @private internal utility of `validatePipelineTasks`
3024
3091
  */
3025
3092
  function validateTaskSupportsJokers(task, pipelineIdentification) {
3026
3093
  if (task.format || task.expectations /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
@@ -3035,7 +3102,7 @@ function validateTaskSupportsJokers(task, pipelineIdentification) {
3035
3102
  /**
3036
3103
  * Validates that every joker parameter is also listed among task dependencies.
3037
3104
  *
3038
- * @private internal utility of `validatePipeline`
3105
+ * @private internal utility of `validatePipelineTasks`
3039
3106
  */
3040
3107
  function validateTaskJokerDependencies(task, pipelineIdentification) {
3041
3108
  for (const joker of task.jokerParameterNames) {
@@ -3052,7 +3119,7 @@ function validateTaskJokerDependencies(task, pipelineIdentification) {
3052
3119
  /**
3053
3120
  * Validates all expectation bounds configured on one task.
3054
3121
  *
3055
- * @private internal utility of `validatePipeline`
3122
+ * @private internal utility of `validatePipelineTasks`
3056
3123
  */
3057
3124
  function validateTaskExpectations(task, pipelineIdentification) {
3058
3125
  if (!task.expectations) {
@@ -3067,7 +3134,7 @@ function validateTaskExpectations(task, pipelineIdentification) {
3067
3134
  /**
3068
3135
  * Validates the minimum and maximum expectation ordering for one unit.
3069
3136
  *
3070
- * @private internal utility of `validatePipeline`
3137
+ * @private internal utility of `validatePipelineTasks`
3071
3138
  */
3072
3139
  function validateTaskExpectationRange(unit, min, max, pipelineIdentification) {
3073
3140
  if (min === undefined || max === undefined || min <= max) {
@@ -3082,7 +3149,7 @@ function validateTaskExpectationRange(unit, min, max, pipelineIdentification) {
3082
3149
  /**
3083
3150
  * Validates the minimum expectation bound for one unit.
3084
3151
  *
3085
- * @private internal utility of `validatePipeline`
3152
+ * @private internal utility of `validatePipelineTasks`
3086
3153
  */
3087
3154
  function validateTaskExpectationMin(unit, min, pipelineIdentification) {
3088
3155
  if (min === undefined || min >= 0) {
@@ -3097,7 +3164,7 @@ function validateTaskExpectationMin(unit, min, pipelineIdentification) {
3097
3164
  /**
3098
3165
  * Validates the maximum expectation bound for one unit.
3099
3166
  *
3100
- * @private internal utility of `validatePipeline`
3167
+ * @private internal utility of `validatePipelineTasks`
3101
3168
  */
3102
3169
  function validateTaskExpectationMax(unit, max, pipelineIdentification) {
3103
3170
  if (max === undefined || max > 0) {
@@ -3109,123 +3176,62 @@ function validateTaskExpectationMax(unit, max, pipelineIdentification) {
3109
3176
  ${block(pipelineIdentification)}
3110
3177
  `));
3111
3178
  }
3179
+
3112
3180
  /**
3113
- * Collects the parameter names that are already resolvable before dependency traversal starts.
3114
- *
3115
- * @private internal utility of `validatePipeline`
3116
- */
3117
- function createInitialDependencyResolutionState(pipeline) {
3118
- return {
3119
- resolvedParameterNames: createInitiallyResolvedParameterNames(pipeline),
3120
- unresolvedTasks: [...pipeline.tasks],
3121
- };
3122
- }
3123
- /**
3124
- * Checks whether dependency resolution still has tasks left to process.
3125
- *
3126
- * @private internal utility of `validatePipeline`
3127
- */
3128
- function hasUnresolvedTasks({ unresolvedTasks }) {
3129
- return unresolvedTasks.length > 0;
3130
- }
3131
- /**
3132
- * Resolves the next batch of currently satisfiable tasks.
3181
+ * Validates PipelineJson if it is logically valid
3133
3182
  *
3134
- * @private internal utility of `validatePipeline`
3135
- */
3136
- function resolveNextDependencyResolutionState(dependencyResolutionState, pipelineIdentification) {
3137
- const currentlyResolvedTasks = getCurrentlyResolvedTasks(dependencyResolutionState.unresolvedTasks, dependencyResolutionState.resolvedParameterNames);
3138
- if (currentlyResolvedTasks.length === 0) {
3139
- throw createUnresolvedTasksError(dependencyResolutionState.unresolvedTasks, dependencyResolutionState.resolvedParameterNames, pipelineIdentification);
3140
- }
3141
- return {
3142
- resolvedParameterNames: appendResolvedTaskParameterNames(dependencyResolutionState.resolvedParameterNames, currentlyResolvedTasks),
3143
- unresolvedTasks: dependencyResolutionState.unresolvedTasks.filter((task) => !currentlyResolvedTasks.includes(task)),
3144
- };
3145
- }
3146
- /**
3147
- * Collects the parameter names that are already resolvable before dependency traversal starts.
3183
+ * It checks:
3184
+ * - if it has correct parameters dependency
3148
3185
  *
3149
- * @private internal utility of `validatePipeline`
3150
- */
3151
- function createInitiallyResolvedParameterNames(pipeline) {
3152
- let resolvedParameterNames = pipeline.parameters
3153
- .filter(({ isInput }) => isInput)
3154
- .map(({ name }) => name);
3155
- for (const reservedParameterName of RESERVED_PARAMETER_NAMES) {
3156
- resolvedParameterNames = [...resolvedParameterNames, reservedParameterName];
3157
- }
3158
- return resolvedParameterNames;
3159
- }
3160
- /**
3161
- * Adds newly resolved task outputs to the resolved parameter list.
3186
+ * It does NOT check:
3187
+ * - if it is valid json
3188
+ * - if it is meaningful
3162
3189
  *
3163
- * @private internal utility of `validatePipeline`
3164
- */
3165
- function appendResolvedTaskParameterNames(resolvedParameterNames, currentlyResolvedTasks) {
3166
- return [
3167
- ...resolvedParameterNames,
3168
- ...currentlyResolvedTasks.map(({ resultingParameterName }) => resultingParameterName),
3169
- ];
3170
- }
3171
- /**
3172
- * Selects tasks whose dependencies are already resolved.
3190
+ * Note: [🔂] This function is idempotent.
3173
3191
  *
3174
- * @private internal utility of `validatePipeline`
3175
- */
3176
- function getCurrentlyResolvedTasks(unresolvedTasks, resolvedParameterNames) {
3177
- return unresolvedTasks.filter((task) => task.dependentParameterNames.every((name) => resolvedParameterNames.includes(name)));
3178
- }
3179
- /**
3180
- * Creates the unexpected loop-limit error for dependency resolution.
3192
+ * @param pipeline valid or invalid PipelineJson
3193
+ * @returns the same pipeline if it is logically valid
3194
+ * @throws {PipelineLogicError} on logical error in the pipeline
3181
3195
  *
3182
- * @private internal utility of `validatePipeline`
3196
+ * @public exported from `@promptbook/core`
3183
3197
  */
3184
- function createDependencyResolutionLoopLimitError(pipelineIdentification) {
3185
- // Note: Really UnexpectedError not LimitReachedError - this should not happen and be caught below
3186
- return new UnexpectedError(spaceTrim$1((block) => `
3187
- Loop limit reached during detection of circular dependencies in \`validatePipeline\`
3198
+ function validatePipeline(pipeline) {
3199
+ if (IS_PIPELINE_LOGIC_VALIDATED) {
3200
+ validatePipeline_InnerFunction(pipeline);
3201
+ }
3202
+ else {
3203
+ try {
3204
+ validatePipeline_InnerFunction(pipeline);
3205
+ }
3206
+ catch (error) {
3207
+ if (!(error instanceof PipelineLogicError)) {
3208
+ throw error;
3209
+ }
3210
+ console.error(spaceTrim$1((block) => `
3211
+ Pipeline is not valid but logic errors are temporarily disabled via \`IS_PIPELINE_LOGIC_VALIDATED\`
3188
3212
 
3189
- ${block(pipelineIdentification)}
3190
- `));
3213
+ ${block(error.message)}
3214
+ `));
3215
+ }
3216
+ }
3217
+ return pipeline;
3191
3218
  }
3192
3219
  /**
3193
- * Creates the detailed error for unresolved or circular task dependencies.
3220
+ * Validates pipeline inner function.
3194
3221
  *
3195
- * @private internal utility of `validatePipeline`
3222
+ * @private internal function for `validatePipeline`
3196
3223
  */
3197
- function createUnresolvedTasksError(unresolvedTasks, resolvedParameterNames, pipelineIdentification) {
3198
- return new PipelineLogicError(
3199
- // TODO: [🐎] DRY
3200
- spaceTrim$1((block) => `
3201
-
3202
- Can not resolve some parameters:
3203
- Either you are using a parameter that is not defined, or there are some circular dependencies.
3204
-
3205
- ${block(pipelineIdentification)}
3206
-
3207
- **Can not resolve:**
3208
- ${block(unresolvedTasks
3209
- .map(({ resultingParameterName, dependentParameterNames }) => `- Parameter \`{${resultingParameterName}}\` which depends on ${dependentParameterNames
3210
- .map((dependentParameterName) => `\`{${dependentParameterName}}\``)
3211
- .join(' and ')}`)
3212
- .join('\n'))}
3213
-
3214
- **Resolved:**
3215
- ${block(resolvedParameterNames
3216
- .filter((name) => !RESERVED_PARAMETER_NAMES.includes(name))
3217
- .map((name) => `- Parameter \`{${name}}\``)
3218
- .join('\n'))}
3219
-
3220
-
3221
- **Reserved (which are available):**
3222
- ${block(resolvedParameterNames
3223
- .filter((name) => RESERVED_PARAMETER_NAMES.includes(name))
3224
- .map((name) => `- Parameter \`{${name}}\``)
3225
- .join('\n'))}
3226
-
3227
-
3228
- `));
3224
+ function validatePipeline_InnerFunction(pipeline) {
3225
+ // TODO: [🧠] Maybe test if promptbook is a promise and make specific error case for that
3226
+ const context = createPipelineValidationContext(pipeline);
3227
+ validatePipelineMetadata(context);
3228
+ validatePipelineCollectionsStructure(context);
3229
+ validatePipelineParameters(context);
3230
+ validatePipelineTasks(context);
3231
+ validatePipelineDependencyResolution(context);
3232
+ // Note: Check that formfactor is corresponding to the pipeline interface
3233
+ // TODO: !!6 Implement this
3234
+ // pipeline.formfactorName
3229
3235
  }
3230
3236
  /**
3231
3237
  * TODO: [🧞‍♀️] Do not allow joker + foreach
@@ -8891,63 +8897,59 @@ const $llmToolsRegister = new $Register('llm_execution_tools_constructors');
8891
8897
  // TODO: [®] DRY Register logic
8892
8898
 
8893
8899
  /**
8894
- * Register for LLM tools metadata.
8895
- *
8896
- * Note: `$` is used to indicate that this interacts with the global scope
8897
- *
8898
- * @singleton Only one instance of each register is created per build, but there can be more instances across different builds or environments.
8900
+ * Path to the `.env` file which was used to configure LLM tools
8899
8901
  *
8900
- * @public exported from `@promptbook/core`
8902
+ * Note: `$` is used to indicate that this variable is changed by side effect in `$provideLlmToolsConfigurationFromEnv` through `$setUsedEnvFilename`
8901
8903
  */
8902
- const $llmToolsMetadataRegister = new $Register('llm_tools_metadata');
8903
- // TODO: [®] DRY Register logic
8904
-
8904
+ let $usedEnvFilename = null;
8905
8905
  /**
8906
- * Creates a message with all registered LLM tools
8907
- *
8908
- * Note: This function is used to create a (error) message when there is no constructor for some LLM provider
8906
+ * Shared state for the `.env` file used to configure LLM tools.
8909
8907
  *
8910
- * @private internal function of `createLlmToolsFromConfiguration` and `$provideLlmToolsFromEnv`
8908
+ * @private internal state of `$registeredLlmToolsMessage`
8911
8909
  */
8912
- function $registeredLlmToolsMessage() {
8913
- const registeredLlmToolsMessageContext = createRegisteredLlmToolsMessageContext();
8914
- if (registeredLlmToolsMessageContext.llmToolStatuses.length === 0) {
8915
- return renderNoRegisteredLlmToolsMessage(registeredLlmToolsMessageContext.usedEnvMessage);
8916
- }
8917
- return renderRegisteredLlmToolsMessage(registeredLlmToolsMessageContext);
8918
- }
8919
- /**
8920
- * Collects all state needed to render the provider summary.
8921
- *
8922
- * @private internal function of `$registeredLlmToolsMessage`
8923
- */
8924
- function createRegisteredLlmToolsMessageContext() {
8925
- const isRunningInNode = $isRunningInNode();
8926
- const env = getAvailableEnvironmentVariables(isRunningInNode);
8927
- const registeredLlmToolRegisters = getRegisteredLlmToolRegisters();
8928
- return {
8929
- env,
8930
- llmToolStatuses: listRegisteredLlmToolStatuses(registeredLlmToolRegisters, env),
8931
- usedEnvMessage: createUsedEnvMessage(),
8932
- isRunningInNode,
8933
- };
8934
- }
8910
+ const USED_ENV_FILENAME = {
8911
+ set(filepath) {
8912
+ $usedEnvFilename = filepath;
8913
+ },
8914
+ createMessage() {
8915
+ return $usedEnvFilename === null
8916
+ ? `Unknown \`.env\` file`
8917
+ : spaceTrim$1(`
8918
+ Used \`.env\` file:
8919
+ ${$usedEnvFilename}
8920
+ `);
8921
+ },
8922
+ };
8923
+
8935
8924
  /**
8936
8925
  * Reads environment variables relevant for provider configuration.
8937
8926
  *
8938
- * @private internal function of `$registeredLlmToolsMessage`
8927
+ * @private function of `$registeredLlmToolsMessage`
8939
8928
  */
8940
- function getAvailableEnvironmentVariables(isRunningInNode) {
8929
+ function getAvailableRegisteredLlmToolsEnvironmentVariables(isRunningInNode) {
8941
8930
  if (isRunningInNode) {
8942
8931
  return process.env;
8943
8932
  // <- TODO: [⚛] Some DRY way how to get to `process.env` and pass it into functions - ACRY search for `env`
8944
8933
  }
8945
8934
  return {};
8946
8935
  }
8936
+
8937
+ /**
8938
+ * Register for LLM tools metadata.
8939
+ *
8940
+ * Note: `$` is used to indicate that this interacts with the global scope
8941
+ *
8942
+ * @singleton Only one instance of each register is created per build, but there can be more instances across different builds or environments.
8943
+ *
8944
+ * @public exported from `@promptbook/core`
8945
+ */
8946
+ const $llmToolsMetadataRegister = new $Register('llm_tools_metadata');
8947
+ // TODO: [®] DRY Register logic
8948
+
8947
8949
  /**
8948
8950
  * Takes stable snapshots of both LLM provider registers.
8949
8951
  *
8950
- * @private internal function of `$registeredLlmToolsMessage`
8952
+ * @private function of `$registeredLlmToolsMessage`
8951
8953
  */
8952
8954
  function getRegisteredLlmToolRegisters() {
8953
8955
  return {
@@ -8955,62 +8957,30 @@ function getRegisteredLlmToolRegisters() {
8955
8957
  registeredTools: $llmToolsRegister.list(),
8956
8958
  };
8957
8959
  }
8958
- /**
8959
- * Lists provider entries enriched with installation and configuration state.
8960
- *
8961
- * @private internal function of `$registeredLlmToolsMessage`
8962
- */
8963
- function listRegisteredLlmToolStatuses({ registeredMetadata, registeredTools }, env) {
8964
- return listRegisteredLlmToolEntries(registeredMetadata, registeredTools).map((registeredLlmToolEntry) => createRegisteredLlmToolStatus({ registeredLlmToolEntry, registeredMetadata, registeredTools, env }));
8965
- }
8966
- /**
8967
- * Merges provider entries from the metadata and constructor registers.
8968
- *
8969
- * @private internal function of `$registeredLlmToolsMessage`
8970
- */
8971
- function listRegisteredLlmToolEntries(registeredMetadata, registeredTools) {
8972
- const registeredLlmToolEntries = new Map();
8973
- for (const { title, packageName, className, envVariables } of registeredMetadata) {
8974
- addRegisteredLlmToolEntry(registeredLlmToolEntries, { title, packageName, className, envVariables });
8975
- }
8976
- for (const { packageName, className } of registeredTools) {
8977
- addRegisteredLlmToolEntry(registeredLlmToolEntries, { packageName, className });
8978
- }
8979
- return [...registeredLlmToolEntries.values()];
8980
- }
8981
- /**
8982
- * Adds a provider entry only when the provider is not already present.
8983
- *
8984
- * @private internal function of `$registeredLlmToolsMessage`
8985
- */
8986
- function addRegisteredLlmToolEntry(registeredLlmToolEntries, registeredLlmToolEntry) {
8987
- const registeredLlmToolEntryKey = createRegisteredLlmToolEntryKey(registeredLlmToolEntry);
8988
- if (registeredLlmToolEntries.has(registeredLlmToolEntryKey)) {
8989
- return;
8990
- }
8991
- registeredLlmToolEntries.set(registeredLlmToolEntryKey, registeredLlmToolEntry);
8992
- }
8960
+
8993
8961
  /**
8994
8962
  * Creates a deduplication key for a provider entry.
8995
8963
  *
8996
- * @private internal function of `$registeredLlmToolsMessage`
8964
+ * @private function of `$registeredLlmToolsMessage`
8997
8965
  */
8998
8966
  function createRegisteredLlmToolEntryKey({ packageName, className }) {
8999
8967
  return `${packageName}::${className}`;
9000
8968
  }
8969
+
9001
8970
  /**
9002
8971
  * Checks whether the given provider entry already exists in the target register list.
9003
8972
  *
9004
- * @private internal function of `$registeredLlmToolsMessage`
8973
+ * @private function of `$registeredLlmToolsMessage`
9005
8974
  */
9006
8975
  function hasRegisteredLlmToolEntry(registeredLlmToolEntries, registeredLlmToolEntry) {
9007
8976
  const registeredLlmToolEntryKey = createRegisteredLlmToolEntryKey(registeredLlmToolEntry);
9008
8977
  return registeredLlmToolEntries.some((listedRegisteredLlmToolEntry) => createRegisteredLlmToolEntryKey(listedRegisteredLlmToolEntry) === registeredLlmToolEntryKey);
9009
8978
  }
8979
+
9010
8980
  /**
9011
8981
  * Builds the runtime status for one provider entry.
9012
8982
  *
9013
- * @private internal function of `$registeredLlmToolsMessage`
8983
+ * @private function of `$registeredLlmToolsMessage`
9014
8984
  */
9015
8985
  function createRegisteredLlmToolStatus({ registeredLlmToolEntry, registeredMetadata, registeredTools, env, }) {
9016
8986
  const availabilityStatus = createRegisteredLlmToolAvailabilityStatus(registeredLlmToolEntry, registeredMetadata, registeredTools);
@@ -9024,7 +8994,7 @@ function createRegisteredLlmToolStatus({ registeredLlmToolEntry, registeredMetad
9024
8994
  /**
9025
8995
  * Resolves whether the provider has metadata and a registered constructor.
9026
8996
  *
9027
- * @private internal function of `$registeredLlmToolsMessage`
8997
+ * @private function of `$registeredLlmToolsMessage`
9028
8998
  */
9029
8999
  function createRegisteredLlmToolAvailabilityStatus(registeredLlmToolEntry, registeredMetadata, registeredTools) {
9030
9000
  return {
@@ -9035,7 +9005,7 @@ function createRegisteredLlmToolAvailabilityStatus(registeredLlmToolEntry, regis
9035
9005
  /**
9036
9006
  * Resolves whether the provider has enough environment variables to be configured.
9037
9007
  *
9038
- * @private internal function of `$registeredLlmToolsMessage`
9008
+ * @private function of `$registeredLlmToolsMessage`
9039
9009
  */
9040
9010
  function createRegisteredLlmToolConfigurationStatus({ envVariables }, env) {
9041
9011
  return {
@@ -9046,7 +9016,7 @@ function createRegisteredLlmToolConfigurationStatus({ envVariables }, env) {
9046
9016
  /**
9047
9017
  * Checks whether all required environment variables are present for a provider.
9048
9018
  *
9049
- * @private internal function of `$registeredLlmToolsMessage`
9019
+ * @private function of `$registeredLlmToolsMessage`
9050
9020
  */
9051
9021
  function isRegisteredLlmToolFullyConfigured(envVariables, env) {
9052
9022
  if (envVariables === undefined || envVariables === null) {
@@ -9057,7 +9027,7 @@ function isRegisteredLlmToolFullyConfigured(envVariables, env) {
9057
9027
  /**
9058
9028
  * Checks whether at least one required environment variable is present for a provider.
9059
9029
  *
9060
- * @private internal function of `$registeredLlmToolsMessage`
9030
+ * @private function of `$registeredLlmToolsMessage`
9061
9031
  */
9062
9032
  function isRegisteredLlmToolPartiallyConfigured(envVariables, env) {
9063
9033
  if (envVariables === undefined || envVariables === null) {
@@ -9065,109 +9035,128 @@ function isRegisteredLlmToolPartiallyConfigured(envVariables, env) {
9065
9035
  }
9066
9036
  return envVariables.some((envVariableName) => env[envVariableName] !== undefined);
9067
9037
  }
9038
+
9068
9039
  /**
9069
- * Renders the fallback message for environments with no registered providers.
9040
+ * Merges provider entries from the metadata and constructor registers.
9070
9041
  *
9071
- * @private internal function of `$registeredLlmToolsMessage`
9042
+ * @private function of `$registeredLlmToolsMessage`
9072
9043
  */
9073
- function renderNoRegisteredLlmToolsMessage(usedEnvMessage) {
9074
- return spaceTrim$1((block) => `
9075
- No LLM providers are available.
9076
-
9077
- ${block(usedEnvMessage)}
9078
- `);
9044
+ function listRegisteredLlmToolEntries(registeredMetadata, registeredTools) {
9045
+ const registeredLlmToolEntries = new Map();
9046
+ for (const { title, packageName, className, envVariables } of registeredMetadata) {
9047
+ addRegisteredLlmToolEntry(registeredLlmToolEntries, { title, packageName, className, envVariables });
9048
+ }
9049
+ for (const { packageName, className } of registeredTools) {
9050
+ addRegisteredLlmToolEntry(registeredLlmToolEntries, { packageName, className });
9051
+ }
9052
+ return [...registeredLlmToolEntries.values()];
9079
9053
  }
9080
9054
  /**
9081
- * Renders the full provider status summary.
9055
+ * Adds a provider entry only when the provider is not already present.
9082
9056
  *
9083
- * @private internal function of `$registeredLlmToolsMessage`
9057
+ * @private function of `$registeredLlmToolsMessage`
9084
9058
  */
9085
- function renderRegisteredLlmToolsMessage({ env, llmToolStatuses, usedEnvMessage, isRunningInNode, }) {
9086
- return spaceTrim$1((block) => `
9087
-
9088
- ${block(usedEnvMessage)}
9089
-
9090
- Relevant environment variables:
9091
- ${block(renderRelevantEnvironmentVariables(env, llmToolStatuses))}
9092
-
9093
- Available LLM providers are:
9094
- ${block(renderAvailableProviders(llmToolStatuses, env, isRunningInNode))}
9095
- `);
9059
+ function addRegisteredLlmToolEntry(registeredLlmToolEntries, registeredLlmToolEntry) {
9060
+ const registeredLlmToolEntryKey = createRegisteredLlmToolEntryKey(registeredLlmToolEntry);
9061
+ if (registeredLlmToolEntries.has(registeredLlmToolEntryKey)) {
9062
+ return;
9063
+ }
9064
+ registeredLlmToolEntries.set(registeredLlmToolEntryKey, registeredLlmToolEntry);
9096
9065
  }
9066
+
9097
9067
  /**
9098
- * Renders the list of environment variables used by at least one registered provider.
9068
+ * Lists provider entries enriched with installation and configuration state.
9099
9069
  *
9100
- * @private internal function of `$registeredLlmToolsMessage`
9070
+ * @private function of `$registeredLlmToolsMessage`
9101
9071
  */
9102
- function renderRelevantEnvironmentVariables(env, llmToolStatuses) {
9103
- return listRelevantEnvironmentVariables(env, llmToolStatuses)
9104
- .map((envVariableName) => `- \`${envVariableName}\``)
9105
- .join('\n');
9072
+ function listRegisteredLlmToolStatuses({ registeredMetadata, registeredTools }, env) {
9073
+ return listRegisteredLlmToolEntries(registeredMetadata, registeredTools).map((registeredLlmToolEntry) => createRegisteredLlmToolStatus({ registeredLlmToolEntry, registeredMetadata, registeredTools, env }));
9106
9074
  }
9075
+
9107
9076
  /**
9108
- * Lists environment variables that are both present and used by at least one provider.
9077
+ * Collects all state needed to render the provider summary.
9109
9078
  *
9110
- * @private internal function of `$registeredLlmToolsMessage`
9079
+ * @private function of `$registeredLlmToolsMessage`
9111
9080
  */
9112
- function listRelevantEnvironmentVariables(env, llmToolStatuses) {
9113
- return Object.keys(env).filter((envVariableName) => llmToolStatuses.some(({ envVariables }) => envVariables === null || envVariables === void 0 ? void 0 : envVariables.includes(envVariableName)));
9081
+ function createRegisteredLlmToolsMessageContext() {
9082
+ const isRunningInNode = $isRunningInNode();
9083
+ const env = getAvailableRegisteredLlmToolsEnvironmentVariables(isRunningInNode);
9084
+ const registeredLlmToolRegisters = getRegisteredLlmToolRegisters();
9085
+ return {
9086
+ env,
9087
+ llmToolStatuses: listRegisteredLlmToolStatuses(registeredLlmToolRegisters, env),
9088
+ usedEnvMessage: USED_ENV_FILENAME.createMessage(),
9089
+ isRunningInNode,
9090
+ };
9114
9091
  }
9092
+
9115
9093
  /**
9116
- * Renders all provider lines in the status summary.
9094
+ * Renders the fallback message for environments with no registered providers.
9117
9095
  *
9118
- * @private internal function of `$registeredLlmToolsMessage`
9096
+ * @private function of `$registeredLlmToolsMessage`
9119
9097
  */
9120
- function renderAvailableProviders(llmToolStatuses, env, isRunningInNode) {
9121
- return llmToolStatuses
9122
- .map((llmToolStatus, index) => renderAvailableProvider(llmToolStatus, index, env, isRunningInNode))
9123
- .join('\n');
9098
+ function renderNoRegisteredLlmToolsMessage(usedEnvMessage) {
9099
+ return spaceTrim$1((block) => `
9100
+ No LLM providers are available.
9101
+
9102
+ ${block(usedEnvMessage)}
9103
+ `);
9124
9104
  }
9105
+
9125
9106
  /**
9126
- * Renders one provider line in the status summary.
9107
+ * Creates the configuration-status sentence for one provider.
9127
9108
  *
9128
- * @private internal function of `$registeredLlmToolsMessage`
9109
+ * @private function of `$registeredLlmToolsMessage`
9129
9110
  */
9130
- function renderAvailableProvider(llmToolStatus, index, env, isRunningInNode) {
9131
- const providerMessage = createAvailableProviderMessage(llmToolStatus, index, env);
9132
- if (!isRunningInNode) {
9133
- return providerMessage;
9111
+ function createRegisteredLlmToolConfigurationStatusMessage({ envVariables, isFullyConfigured, isPartiallyConfigured }, env) {
9112
+ if (isFullyConfigured) {
9113
+ return `Configured`;
9134
9114
  }
9135
- return colorizeAvailableProviderMessage(providerMessage, llmToolStatus);
9115
+ if (isPartiallyConfigured) {
9116
+ return createPartiallyConfiguredStatusMessage(envVariables, env);
9117
+ }
9118
+ if (envVariables !== null) {
9119
+ return createNotConfiguredStatusMessage(envVariables);
9120
+ }
9121
+ return `Not configured`;
9122
+ // <- Note: Can not be configured via environment variables
9136
9123
  }
9137
9124
  /**
9138
- * Creates the plain-text provider line before optional colorization.
9125
+ * Creates the partial-configuration sentence including missing variables.
9139
9126
  *
9140
- * @private internal function of `$registeredLlmToolsMessage`
9127
+ * @private function of `$registeredLlmToolsMessage`
9141
9128
  */
9142
- function createAvailableProviderMessage(llmToolStatus, index, env) {
9143
- const { title, packageName, className } = llmToolStatus;
9144
- const providerStatusMessages = createProviderStatusMessages(llmToolStatus, env);
9145
- return spaceTrim$1(`
9146
- ${index + 1}) **${title}** \`${className}\` from \`${packageName}\`
9147
- ${providerStatusMessages.join('; ')}
9148
- `);
9129
+ function createPartiallyConfiguredStatusMessage(envVariables, env) {
9130
+ return `Partially confugured, missing ${listMissingEnvironmentVariables(envVariables, env).join(' + ')}`;
9149
9131
  }
9150
9132
  /**
9151
- * Creates the install and configuration fragments for one provider line.
9133
+ * Creates the not-configured sentence including the expected environment variables.
9152
9134
  *
9153
- * @private internal function of `$registeredLlmToolsMessage`
9135
+ * @private function of `$registeredLlmToolsMessage`
9154
9136
  */
9155
- function createProviderStatusMessages(llmToolStatus, env) {
9156
- return [createInstallationStatusMessage(llmToolStatus), createConfigurationStatusMessage(llmToolStatus, env)];
9137
+ function createNotConfiguredStatusMessage(envVariables) {
9138
+ return `Not configured, to configure set env ${envVariables === null || envVariables === void 0 ? void 0 : envVariables.join(' + ')}`;
9157
9139
  }
9140
+ /**
9141
+ * Lists environment variables that are required but currently missing.
9142
+ *
9143
+ * @private function of `$registeredLlmToolsMessage`
9144
+ */
9145
+ function listMissingEnvironmentVariables(envVariables, env) {
9146
+ return (envVariables === null || envVariables === void 0 ? void 0 : envVariables.filter((envVariable) => env[envVariable] === undefined)) || [];
9147
+ }
9148
+
9158
9149
  /**
9159
9150
  * Creates the installation-status sentence for one provider.
9160
9151
  *
9161
- * @private internal function of `$registeredLlmToolsMessage`
9152
+ * @private function of `$registeredLlmToolsMessage`
9162
9153
  */
9163
- function createInstallationStatusMessage({ isMetadataAvailable, isInstalled, }) {
9164
- const installationStatusKey = createInstallationStatusKey(isMetadataAvailable, isInstalled);
9154
+ function createRegisteredLlmToolInstallationStatusMessage({ isMetadataAvailable, isInstalled, }) {
9155
+ const installationStatusKey = createRegisteredLlmToolInstallationStatusKey(isMetadataAvailable, isInstalled);
9165
9156
  switch (installationStatusKey) {
9166
9157
  case 'missing-metadata-and-installation':
9167
- // TODO: [�][�] Maybe do allow to do auto-install if package not registered and not found
9168
9158
  return `Not installed and no metadata, looks like a unexpected behavior`;
9169
9159
  case 'metadata-without-installation':
9170
- // TODO: [�][�]
9171
9160
  return `Not installed`;
9172
9161
  case 'installation-without-metadata':
9173
9162
  return `No metadata but installed, looks like a unexpected behavior`;
@@ -9180,9 +9169,9 @@ function createInstallationStatusMessage({ isMetadataAvailable, isInstalled, })
9180
9169
  /**
9181
9170
  * Creates a stable installation-state key from metadata and constructor availability.
9182
9171
  *
9183
- * @private internal function of `$registeredLlmToolsMessage`
9172
+ * @private function of `$registeredLlmToolsMessage`
9184
9173
  */
9185
- function createInstallationStatusKey(isMetadataAvailable, isInstalled) {
9174
+ function createRegisteredLlmToolInstallationStatusKey(isMetadataAvailable, isInstalled) {
9186
9175
  if (!isMetadataAvailable && !isInstalled) {
9187
9176
  return 'missing-metadata-and-installation';
9188
9177
  }
@@ -9197,54 +9186,59 @@ function createInstallationStatusKey(isMetadataAvailable, isInstalled) {
9197
9186
  }
9198
9187
  return 'unknown';
9199
9188
  }
9189
+
9200
9190
  /**
9201
- * Creates the configuration-status sentence for one provider.
9191
+ * Renders all provider lines in the status summary.
9202
9192
  *
9203
- * @private internal function of `$registeredLlmToolsMessage`
9193
+ * @private function of `$registeredLlmToolsMessage`
9204
9194
  */
9205
- function createConfigurationStatusMessage({ envVariables, isFullyConfigured, isPartiallyConfigured }, env) {
9206
- if (isFullyConfigured) {
9207
- return `Configured`;
9208
- }
9209
- if (isPartiallyConfigured) {
9210
- return createPartiallyConfiguredStatusMessage(envVariables, env);
9211
- }
9212
- if (envVariables !== null) {
9213
- return createNotConfiguredStatusMessage(envVariables);
9214
- }
9215
- return `Not configured`;
9216
- // <- Note: Can not be configured via environment variables
9195
+ function renderAvailableRegisteredLlmTools(llmToolStatuses, env, isRunningInNode) {
9196
+ return llmToolStatuses
9197
+ .map((llmToolStatus, index) => renderAvailableRegisteredLlmTool(llmToolStatus, index, env, isRunningInNode))
9198
+ .join('\n');
9217
9199
  }
9218
9200
  /**
9219
- * Creates the partial-configuration sentence including missing variables.
9201
+ * Renders one provider line in the status summary.
9220
9202
  *
9221
- * @private internal function of `$registeredLlmToolsMessage`
9203
+ * @private function of `$registeredLlmToolsMessage`
9222
9204
  */
9223
- function createPartiallyConfiguredStatusMessage(envVariables, env) {
9224
- return `Partially confugured, missing ${listMissingEnvironmentVariables(envVariables, env).join(' + ')}`;
9205
+ function renderAvailableRegisteredLlmTool(llmToolStatus, index, env, isRunningInNode) {
9206
+ const providerMessage = createAvailableRegisteredLlmToolMessage(llmToolStatus, index, env);
9207
+ if (!isRunningInNode) {
9208
+ return providerMessage;
9209
+ }
9210
+ return colorizeAvailableRegisteredLlmToolMessage(providerMessage, llmToolStatus);
9225
9211
  }
9226
9212
  /**
9227
- * Creates the not-configured sentence including the expected environment variables.
9213
+ * Creates the plain-text provider line before optional colorization.
9228
9214
  *
9229
- * @private internal function of `$registeredLlmToolsMessage`
9215
+ * @private function of `$registeredLlmToolsMessage`
9230
9216
  */
9231
- function createNotConfiguredStatusMessage(envVariables) {
9232
- return `Not configured, to configure set env ${envVariables === null || envVariables === void 0 ? void 0 : envVariables.join(' + ')}`;
9217
+ function createAvailableRegisteredLlmToolMessage(llmToolStatus, index, env) {
9218
+ const { title, packageName, className } = llmToolStatus;
9219
+ const providerStatusMessages = createRegisteredLlmToolStatusMessages(llmToolStatus, env);
9220
+ return spaceTrim$1(`
9221
+ ${index + 1}) **${title}** \`${className}\` from \`${packageName}\`
9222
+ ${providerStatusMessages.join('; ')}
9223
+ `);
9233
9224
  }
9234
9225
  /**
9235
- * Lists environment variables that are required but currently missing.
9226
+ * Creates the install and configuration fragments for one provider line.
9236
9227
  *
9237
- * @private internal function of `$registeredLlmToolsMessage`
9228
+ * @private function of `$registeredLlmToolsMessage`
9238
9229
  */
9239
- function listMissingEnvironmentVariables(envVariables, env) {
9240
- return (envVariables === null || envVariables === void 0 ? void 0 : envVariables.filter((envVariable) => env[envVariable] === undefined)) || [];
9230
+ function createRegisteredLlmToolStatusMessages(llmToolStatus, env) {
9231
+ return [
9232
+ createRegisteredLlmToolInstallationStatusMessage(llmToolStatus),
9233
+ createRegisteredLlmToolConfigurationStatusMessage(llmToolStatus, env),
9234
+ ];
9241
9235
  }
9242
9236
  /**
9243
9237
  * Applies the same terminal coloring rules as the original summary renderer.
9244
9238
  *
9245
- * @private internal function of `$registeredLlmToolsMessage`
9239
+ * @private function of `$registeredLlmToolsMessage`
9246
9240
  */
9247
- function colorizeAvailableProviderMessage(providerMessage, { isInstalled, isFullyConfigured, isPartiallyConfigured }) {
9241
+ function colorizeAvailableRegisteredLlmToolMessage(providerMessage, { isInstalled, isFullyConfigured, isPartiallyConfigured }) {
9248
9242
  if (isInstalled && isFullyConfigured) {
9249
9243
  return colors.green(providerMessage);
9250
9244
  }
@@ -9253,14 +9247,57 @@ function colorizeAvailableProviderMessage(providerMessage, { isInstalled, isFull
9253
9247
  }
9254
9248
  return colors.gray(providerMessage);
9255
9249
  }
9250
+
9251
+ /**
9252
+ * Renders the list of environment variables used by at least one registered provider.
9253
+ *
9254
+ * @private function of `$registeredLlmToolsMessage`
9255
+ */
9256
+ function renderRelevantRegisteredLlmToolsEnvironmentVariables(env, llmToolStatuses) {
9257
+ return listRelevantRegisteredLlmToolsEnvironmentVariables(env, llmToolStatuses)
9258
+ .map((envVariableName) => `- \`${envVariableName}\``)
9259
+ .join('\n');
9260
+ }
9256
9261
  /**
9257
- * Creates the `.env` origin sentence used in the summary header.
9262
+ * Lists environment variables that are both present and used by at least one provider.
9263
+ *
9264
+ * @private function of `$registeredLlmToolsMessage`
9265
+ */
9266
+ function listRelevantRegisteredLlmToolsEnvironmentVariables(env, llmToolStatuses) {
9267
+ return Object.keys(env).filter((envVariableName) => llmToolStatuses.some(({ envVariables }) => envVariables === null || envVariables === void 0 ? void 0 : envVariables.includes(envVariableName)));
9268
+ }
9269
+
9270
+ /**
9271
+ * Renders the full provider status summary.
9258
9272
  *
9259
- * @private internal function of `$registeredLlmToolsMessage`
9273
+ * @private function of `$registeredLlmToolsMessage`
9260
9274
  */
9261
- function createUsedEnvMessage() {
9262
- return `Unknown \`.env\` file`
9263
- ;
9275
+ function renderRegisteredLlmToolsMessage({ env, llmToolStatuses, usedEnvMessage, isRunningInNode, }) {
9276
+ return spaceTrim$1((block) => `
9277
+
9278
+ ${block(usedEnvMessage)}
9279
+
9280
+ Relevant environment variables:
9281
+ ${block(renderRelevantRegisteredLlmToolsEnvironmentVariables(env, llmToolStatuses))}
9282
+
9283
+ Available LLM providers are:
9284
+ ${block(renderAvailableRegisteredLlmTools(llmToolStatuses, env, isRunningInNode))}
9285
+ `);
9286
+ }
9287
+
9288
+ /**
9289
+ * Creates a message with all registered LLM tools
9290
+ *
9291
+ * Note: This function is used to create a (error) message when there is no constructor for some LLM provider
9292
+ *
9293
+ * @private internal function of `createLlmToolsFromConfiguration` and `$provideLlmToolsFromEnv`
9294
+ */
9295
+ function $registeredLlmToolsMessage() {
9296
+ const registeredLlmToolsMessageContext = createRegisteredLlmToolsMessageContext();
9297
+ if (registeredLlmToolsMessageContext.llmToolStatuses.length === 0) {
9298
+ return renderNoRegisteredLlmToolsMessage(registeredLlmToolsMessageContext.usedEnvMessage);
9299
+ }
9300
+ return renderRegisteredLlmToolsMessage(registeredLlmToolsMessageContext);
9264
9301
  }
9265
9302
  // TODO: [®] DRY Register logic
9266
9303
  // TODO: [🧠][⚛] Maybe pass env as argument
@@ -12896,7 +12933,7 @@ class MessageSuffixCommitmentDefinition extends BaseCommitmentDefinition {
12896
12933
  * META commitment definition
12897
12934
  *
12898
12935
  * The META commitment handles all meta-information about the agent such as:
12899
- * - META AVATAR: Sets the agent's built-in default avatar visual
12936
+ * - META AVATAR / META VISUAL: Sets the agent's built-in default avatar visual
12900
12937
  * - META IMAGE: Sets the agent's avatar/profile image URL
12901
12938
  * - META LINK: Provides profile/source links for the person the agent models
12902
12939
  * - META DOMAIN: Sets the canonical custom domain/host of the agent
@@ -12911,7 +12948,7 @@ class MessageSuffixCommitmentDefinition extends BaseCommitmentDefinition {
12911
12948
  * Example usage in agent source:
12912
12949
  *
12913
12950
  * ```book
12914
- * META AVATAR pixel-art
12951
+ * META VISUAL pixel-art
12915
12952
  * META IMAGE https://example.com/avatar.jpg
12916
12953
  * META LINK https://twitter.com/username
12917
12954
  * META DOMAIN my-agent.com
@@ -12951,7 +12988,7 @@ class MetaCommitmentDefinition extends BaseCommitmentDefinition {
12951
12988
 
12952
12989
  ## Supported META types
12953
12990
 
12954
- - **META AVATAR** - Sets the agent's built-in default avatar visual
12991
+ - **META AVATAR** / **META VISUAL** - Sets the agent's built-in default avatar visual
12955
12992
  - **META IMAGE** - Sets the agent's avatar/profile image URL
12956
12993
  - **META LINK** - Provides profile/source links for the person the agent models
12957
12994
  - **META DOMAIN** - Sets the canonical custom domain/host of the agent
@@ -12975,7 +13012,7 @@ class MetaCommitmentDefinition extends BaseCommitmentDefinition {
12975
13012
  \`\`\`book
12976
13013
  Professional Assistant
12977
13014
 
12978
- META AVATAR octopus3
13015
+ META VISUAL octopus3
12979
13016
  META IMAGE https://example.com/professional-avatar.jpg
12980
13017
  META TITLE Senior Business Consultant
12981
13018
  META DESCRIPTION Specialized in strategic planning and project management
@@ -16146,452 +16183,13 @@ function formatAlphaHex$1(opacity) {
16146
16183
  .padStart(2, '0');
16147
16184
  }
16148
16185
 
16149
- /* eslint-disable no-magic-numbers */
16150
- /**
16151
- * Light direction used by the organic 3D octopus shading.
16152
- *
16153
- * @private helper of `octopus3dAvatarVisual`
16154
- */
16155
- const LIGHT_DIRECTION$3 = normalizeVector3({
16156
- x: 0.48,
16157
- y: -0.62,
16158
- z: 0.94,
16159
- });
16160
- /**
16161
- * Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
16162
- *
16163
- * @private helper of `octopus3dAvatarVisual`
16164
- */
16165
- const octopus3dStableStateCache = new WeakMap();
16166
- /**
16167
- * Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
16168
- *
16169
- * @private helper of `octopus3dAvatarVisual`
16170
- */
16171
- function getOctopus3dStableState(createRandom) {
16172
- const cached = octopus3dStableStateCache.get(createRandom);
16173
- if (cached !== undefined) {
16174
- return cached;
16175
- }
16176
- const animationRandom = createRandom('octopus3d-animation-profile');
16177
- const eyeRandom = createRandom('octopus3d-eye-profile');
16178
- const leftEyePhaseOffset = eyeRandom() * 0.6;
16179
- const rightEyePhaseOffset = eyeRandom() * 0.6;
16180
- const state = {
16181
- morphologyProfile: createOctopus3MorphologyProfile(createRandom),
16182
- animationPhase: animationRandom() * Math.PI * 2,
16183
- leftEyePhaseOffset,
16184
- rightEyePhaseOffset,
16185
- };
16186
- octopus3dStableStateCache.set(createRandom, state);
16187
- return state;
16188
- }
16189
- /**
16190
- * Proper 3D Octopus visual built from projected organic meshes and tentacles.
16191
- *
16192
- * @private built-in avatar visual
16193
- */
16194
- const octopus3dAvatarVisual = {
16195
- id: 'octopus3d',
16196
- title: 'Octopus 3D',
16197
- description: 'Proper 3D octopus portrait with a turning silhouette, expressive eyes, and depth-sorted tentacles.',
16198
- isAnimated: true,
16199
- supportsPointerTracking: true,
16200
- render({ context, size, palette, createRandom, timeMs, interaction }) {
16201
- const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3dStableState(createRandom);
16202
- const sceneCenterX = size * 0.5;
16203
- const sceneCenterY = size * 0.56;
16204
- const bob = Math.sin(timeMs / 920 + animationPhase) * size * 0.014;
16205
- const mantleCenter = {
16206
- x: interaction.bodyOffsetX * size * 0.042 + size * morphologyProfile.body.centerXJitterRatio * 0.65,
16207
- y: -size * 0.09 + interaction.bodyOffsetY * size * 0.028 + bob,
16208
- z: interaction.intensity * size * 0.012,
16209
- };
16210
- const underbodyCenter = {
16211
- x: mantleCenter.x * 0.86,
16212
- y: mantleCenter.y + size * 0.168,
16213
- z: mantleCenter.z - size * 0.018,
16214
- };
16215
- const mantleRadiusX = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.horizontalStretch;
16216
- const mantleRadiusY = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.verticalStretch * 1.1;
16217
- const mantleRadiusZ = size *
16218
- morphologyProfile.body.bodyRadiusRatio *
16219
- (0.9 + (morphologyProfile.body.horizontalStretch - 1) * 0.3);
16220
- const underbodyRadiusX = mantleRadiusX * (0.9 + (morphologyProfile.tentacles.rootSpreadScale - 1) * 0.08);
16221
- const underbodyRadiusY = mantleRadiusY * (0.44 + morphologyProfile.body.lowerDropRatio * 3.1);
16222
- const underbodyRadiusZ = mantleRadiusZ * 0.78;
16223
- const bodyYaw = -0.18 +
16224
- Math.sin(timeMs / 2400 + animationPhase) * 0.05 +
16225
- interaction.bodyOffsetX * 0.18 +
16226
- interaction.gazeX * 0.22;
16227
- const bodyPitch = -0.08 +
16228
- Math.cos(timeMs / 2700 + animationPhase * 0.6) * 0.025 -
16229
- interaction.bodyOffsetY * 0.08 -
16230
- interaction.gazeY * 0.08;
16231
- const headYaw = bodyYaw - 0.04 + interaction.gazeX * 0.56;
16232
- const headPitch = bodyPitch - 0.02 - interaction.gazeY * 0.32;
16233
- const mantlePatches = resolveVisibleEllipsoidPatches({
16234
- center: mantleCenter,
16235
- radiusX: mantleRadiusX,
16236
- radiusY: mantleRadiusY,
16237
- radiusZ: mantleRadiusZ,
16238
- rotationX: headPitch,
16239
- rotationY: headYaw,
16240
- sceneCenterX,
16241
- sceneCenterY,
16242
- size,
16243
- palette,
16244
- verticalColorBias: 0,
16245
- outlineColor: `${palette.highlight}7a`,
16246
- });
16247
- const underbodyPatches = resolveVisibleEllipsoidPatches({
16248
- center: underbodyCenter,
16249
- radiusX: underbodyRadiusX,
16250
- radiusY: underbodyRadiusY,
16251
- radiusZ: underbodyRadiusZ,
16252
- rotationX: bodyPitch,
16253
- rotationY: bodyYaw,
16254
- sceneCenterX,
16255
- sceneCenterY,
16256
- size,
16257
- palette,
16258
- verticalColorBias: 0.18,
16259
- outlineColor: `${palette.shadow}8f`,
16260
- });
16261
- const tentacleStrokes = createOctopusTentacleStrokes({
16262
- createRandom,
16263
- morphologyProfile,
16264
- timeMs,
16265
- size,
16266
- center: underbodyCenter,
16267
- radiusX: underbodyRadiusX,
16268
- radiusY: underbodyRadiusY,
16269
- radiusZ: underbodyRadiusZ,
16270
- rotationX: bodyPitch,
16271
- rotationY: bodyYaw,
16272
- sceneCenterX,
16273
- sceneCenterY,
16274
- animationPhase,
16275
- });
16276
- const faceEyeSpacing = size * morphologyProfile.face.eyeSpacingRatio * 0.92;
16277
- const faceEyeYOffset = size * morphologyProfile.face.eyeCenterYOffsetRatio - mantleRadiusY * 0.02;
16278
- const faceEyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio * 0.82;
16279
- const faceEyeRadiusY = faceEyeRadiusX * morphologyProfile.face.eyeHeightRatio * 0.96;
16280
- const mouthHalfWidth = size * morphologyProfile.face.mouthWidthRatio * 0.92;
16281
- const mouthY = size * morphologyProfile.face.mouthYOffsetRatio + mantleRadiusY * 0.08;
16282
- drawAvatarFrame(context, size, palette);
16283
- drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs);
16284
- drawOctopus3dShadow(context, size, palette, interaction, timeMs);
16285
- for (const tentacleStroke of tentacleStrokes.filter((candidateTentacleStroke) => !candidateTentacleStroke.isFrontFacing)) {
16286
- drawTentacleStroke(context, tentacleStroke, palette);
16287
- }
16288
- for (const surfacePatch of [...mantlePatches, ...underbodyPatches].sort((firstSurfacePatch, secondSurfacePatch) => firstSurfacePatch.averageDepth - secondSurfacePatch.averageDepth)) {
16289
- drawSurfacePatch(context, surfacePatch);
16290
- }
16291
- for (const tentacleStroke of tentacleStrokes.filter((candidateTentacleStroke) => candidateTentacleStroke.isFrontFacing)) {
16292
- drawTentacleStroke(context, tentacleStroke, palette);
16293
- }
16294
- drawProjectedOrganicEye(context, {
16295
- x: -faceEyeSpacing,
16296
- y: faceEyeYOffset,
16297
- z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -faceEyeSpacing, faceEyeYOffset),
16298
- }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
16299
- drawProjectedOrganicEye(context, {
16300
- x: faceEyeSpacing,
16301
- y: faceEyeYOffset,
16302
- z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
16303
- }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
16304
- drawProjectedOrganicMouth(context, [
16305
- {
16306
- x: -mouthHalfWidth,
16307
- y: mouthY,
16308
- z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -mouthHalfWidth, mouthY),
16309
- },
16310
- {
16311
- x: size * morphologyProfile.face.mouthCenterOffsetRatio,
16312
- y: mouthY +
16313
- size * morphologyProfile.face.mouthCurveDepthRatio * 0.38 +
16314
- Math.sin(timeMs / 760 + animationPhase) * size * 0.01 +
16315
- interaction.gazeY * size * 0.01,
16316
- z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, size * morphologyProfile.face.mouthCenterOffsetRatio, mouthY),
16317
- },
16318
- {
16319
- x: mouthHalfWidth,
16320
- y: mouthY,
16321
- z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, mouthHalfWidth, mouthY),
16322
- },
16323
- ], mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, palette, size);
16324
- },
16325
- };
16326
- /**
16327
- * Draws the atmospheric underwater glow behind the octopus mesh.
16328
- *
16329
- * @private helper of `octopus3dAvatarVisual`
16330
- */
16331
- function drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs) {
16332
- 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);
16333
- glowGradient.addColorStop(0, `${palette.highlight}5c`);
16334
- glowGradient.addColorStop(0.36, `${palette.accent}24`);
16335
- glowGradient.addColorStop(1, `${palette.highlight}00`);
16336
- context.fillStyle = glowGradient;
16337
- context.fillRect(0, 0, size, size);
16338
- 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);
16339
- lowerGradient.addColorStop(0, `${palette.secondary}1d`);
16340
- lowerGradient.addColorStop(1, `${palette.secondary}00`);
16341
- context.fillStyle = lowerGradient;
16342
- context.fillRect(0, 0, size, size);
16343
- }
16344
- /**
16345
- * Draws the soft ground shadow below the octopus.
16346
- *
16347
- * Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
16348
- * blurry ellipse without triggering a costly software rasterization pass on every frame.
16349
- *
16350
- * @private helper of `octopus3dAvatarVisual`
16351
- */
16352
- function drawOctopus3dShadow(context, size, palette, interaction, timeMs) {
16353
- const cx = size * 0.5 + interaction.gazeX * size * 0.04;
16354
- const cy = size * 0.87 + Math.sin(timeMs / 920) * size * 0.008;
16355
- const rx = size * (0.18 + interaction.intensity * 0.02);
16356
- const ry = size * 0.06;
16357
- context.save();
16358
- context.translate(cx, cy);
16359
- context.scale(1, ry / rx);
16360
- const blurRadius = rx * 1.4;
16361
- const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
16362
- shadowGradient.addColorStop(0, `${palette.shadow}7a`);
16363
- shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
16364
- shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
16365
- shadowGradient.addColorStop(1, `${palette.shadow}00`);
16366
- context.fillStyle = shadowGradient;
16367
- context.beginPath();
16368
- context.arc(0, 0, blurRadius, 0, Math.PI * 2);
16369
- context.fill();
16370
- context.restore();
16371
- }
16372
- /**
16373
- * Resolves visible projected patches for one rotated ellipsoid mesh.
16374
- *
16375
- * @private helper of `octopus3dAvatarVisual`
16376
- */
16377
- function resolveVisibleEllipsoidPatches(options) {
16378
- const { center, radiusX, radiusY, radiusZ, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, verticalColorBias, outlineColor, } = options;
16379
- const latitudePatchCount = 10;
16380
- const longitudePatchCount = 18;
16381
- const surfacePatches = [];
16382
- for (let latitudeIndex = 0; latitudeIndex < latitudePatchCount; latitudeIndex++) {
16383
- const startLatitude = -Math.PI / 2 + (latitudeIndex / latitudePatchCount) * Math.PI;
16384
- const endLatitude = -Math.PI / 2 + ((latitudeIndex + 1) / latitudePatchCount) * Math.PI;
16385
- const verticalProgress = (latitudeIndex + 0.5) / latitudePatchCount;
16386
- for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
16387
- const startLongitude = -Math.PI + (longitudeIndex / longitudePatchCount) * Math.PI * 2;
16388
- const endLongitude = -Math.PI + ((longitudeIndex + 1) / longitudePatchCount) * Math.PI * 2;
16389
- const localCorners = [
16390
- sampleEllipsoidPoint(radiusX, radiusY, radiusZ, startLatitude, startLongitude),
16391
- sampleEllipsoidPoint(radiusX, radiusY, radiusZ, startLatitude, endLongitude),
16392
- sampleEllipsoidPoint(radiusX, radiusY, radiusZ, endLatitude, endLongitude),
16393
- sampleEllipsoidPoint(radiusX, radiusY, radiusZ, endLatitude, startLongitude),
16394
- ];
16395
- const transformedCorners = localCorners.map((localCorner) => transformScenePoint(localCorner, center, rotationX, rotationY));
16396
- const surfaceNormal = normalizeVector3(crossProduct3D(subtractPoint3D(transformedCorners[1], transformedCorners[0]), subtractPoint3D(transformedCorners[2], transformedCorners[0])));
16397
- if (surfaceNormal.z <= 0.01) {
16398
- continue;
16399
- }
16400
- const projectedCorners = transformedCorners.map((transformedCorner) => projectScenePoint(transformedCorner, size, sceneCenterX, sceneCenterY));
16401
- surfacePatches.push({
16402
- corners: projectedCorners,
16403
- averageDepth: transformedCorners.reduce((depthSum, transformedCorner) => depthSum + transformedCorner.z, 0) /
16404
- transformedCorners.length,
16405
- lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$3), -1, 1),
16406
- fillStyle: resolveSurfacePatchFillStyle(palette, verticalProgress + verticalColorBias),
16407
- outlineColor,
16408
- });
16409
- }
16410
- }
16411
- return surfacePatches;
16412
- }
16413
- /**
16414
- * Samples one point on an ellipsoid aligned to the local axes.
16415
- *
16416
- * @private helper of `octopus3dAvatarVisual`
16417
- */
16418
- function sampleEllipsoidPoint(radiusX, radiusY, radiusZ, latitude, longitude) {
16419
- const cosineLatitude = Math.cos(latitude);
16420
- return {
16421
- x: Math.sin(longitude) * cosineLatitude * radiusX,
16422
- y: Math.sin(latitude) * radiusY,
16423
- z: Math.cos(longitude) * cosineLatitude * radiusZ,
16424
- };
16425
- }
16426
- /**
16427
- * Resolves one base fill tone for a surface patch across the octopus body.
16428
- *
16429
- * @private helper of `octopus3dAvatarVisual`
16430
- */
16431
- function resolveSurfacePatchFillStyle(palette, verticalProgress) {
16432
- const clampedVerticalProgress = clampNumber$1(verticalProgress, 0, 1);
16433
- if (clampedVerticalProgress < 0.2) {
16434
- return palette.highlight;
16435
- }
16436
- if (clampedVerticalProgress < 0.45) {
16437
- return palette.secondary;
16438
- }
16439
- if (clampedVerticalProgress < 0.8) {
16440
- return palette.primary;
16441
- }
16442
- return `${palette.shadow}f2`;
16443
- }
16444
- /**
16445
- * Draws one projected mesh patch with organic shading.
16446
- *
16447
- * @private helper of `octopus3dAvatarVisual`
16448
- */
16449
- function drawSurfacePatch(context, surfacePatch) {
16450
- drawProjectedQuad(context, surfacePatch.corners, surfacePatch.fillStyle);
16451
- if (surfacePatch.lightIntensity > 0) {
16452
- drawProjectedQuad(context, surfacePatch.corners, `rgba(255, 255, 255, ${0.15 * surfacePatch.lightIntensity})`);
16453
- }
16454
- else if (surfacePatch.lightIntensity < 0) {
16455
- drawProjectedQuad(context, surfacePatch.corners, `rgba(0, 0, 0, ${0.24 * Math.abs(surfacePatch.lightIntensity)})`);
16456
- }
16457
- context.save();
16458
- context.beginPath();
16459
- context.moveTo(surfacePatch.corners[0].x, surfacePatch.corners[0].y);
16460
- for (let cornerIndex = 1; cornerIndex < surfacePatch.corners.length; cornerIndex++) {
16461
- context.lineTo(surfacePatch.corners[cornerIndex].x, surfacePatch.corners[cornerIndex].y);
16462
- }
16463
- context.closePath();
16464
- context.strokeStyle = surfacePatch.outlineColor;
16465
- context.lineWidth = Math.max(1, getProjectedQuadPerimeter(surfacePatch.corners) * 0.0044);
16466
- context.lineJoin = 'round';
16467
- context.stroke();
16468
- context.restore();
16469
- }
16470
- /**
16471
- * Creates the projected 3D tentacle strokes orbiting around the lower octopus body.
16472
- *
16473
- * @private helper of `octopus3dAvatarVisual`
16474
- */
16475
- function createOctopusTentacleStrokes(options) {
16476
- const { createRandom, morphologyProfile, timeMs, size, center, radiusX, radiusY, radiusZ, rotationX, rotationY, sceneCenterX, sceneCenterY, animationPhase, } = options;
16477
- return Array.from({ length: morphologyProfile.tentacles.count }, (_, tentacleIndex) => {
16478
- const tentacleRandom = createRandom(`octopus3d-tentacle-${tentacleIndex}`);
16479
- const spreadProgress = morphologyProfile.tentacles.count === 1 ? 0.5 : tentacleIndex / (morphologyProfile.tentacles.count - 1);
16480
- const orbitAngle = -Math.PI * 0.92 + spreadProgress * Math.PI * 1.84 + (tentacleRandom() - 0.5) * 0.16;
16481
- const flowLength = size * (0.19 + morphologyProfile.tentacles.flowLengthScale * 0.075 + tentacleRandom() * 0.018);
16482
- const lateralReach = size *
16483
- (0.08 + morphologyProfile.tentacles.lateralReachScale * 0.05 + Math.abs(Math.sin(orbitAngle)) * 0.018);
16484
- const depthReach = size * (0.028 + morphologyProfile.tentacles.tipReachScale * 0.032);
16485
- const sway = Math.sin(timeMs / (760 + tentacleIndex * 36) + animationPhase + tentacleRandom() * Math.PI * 2);
16486
- const anchorPoint = {
16487
- x: Math.sin(orbitAngle) * radiusX * (0.84 + tentacleRandom() * 0.08),
16488
- y: radiusY * (0.22 + tentacleRandom() * 0.18),
16489
- z: Math.cos(orbitAngle) * radiusZ * (0.72 + tentacleRandom() * 0.12),
16490
- };
16491
- const controlPointOne = {
16492
- x: anchorPoint.x + Math.sin(orbitAngle) * lateralReach * 0.44,
16493
- y: anchorPoint.y + flowLength * 0.26,
16494
- z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.3 + sway * size * 0.012,
16495
- };
16496
- const controlPointTwo = {
16497
- x: anchorPoint.x +
16498
- Math.sin(orbitAngle) * lateralReach * (0.82 + morphologyProfile.tentacles.swayScale * 0.12),
16499
- y: anchorPoint.y + flowLength * 0.66,
16500
- z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.72 + sway * size * 0.02,
16501
- };
16502
- const endPoint = {
16503
- x: anchorPoint.x +
16504
- Math.sin(orbitAngle) * lateralReach * (1.02 + morphologyProfile.tentacles.tipWidthScale * 0.12) +
16505
- sway * size * 0.028,
16506
- y: anchorPoint.y + flowLength,
16507
- z: anchorPoint.z + Math.cos(orbitAngle) * depthReach + sway * size * 0.016,
16508
- };
16509
- const scenePoints = Array.from({ length: 12 }, (_, sampleIndex) => transformScenePoint(sampleCubicBezierPoint3D(anchorPoint, controlPointOne, controlPointTwo, endPoint, sampleIndex / 11), center, rotationX, rotationY));
16510
- const projectedPoints = scenePoints.map((scenePoint) => projectScenePoint(scenePoint, size, sceneCenterX, sceneCenterY));
16511
- const averageDepth = scenePoints.reduce((depthSum, scenePoint) => depthSum + scenePoint.z, 0) / scenePoints.length;
16512
- return {
16513
- projectedPoints,
16514
- averageDepth,
16515
- isFrontFacing: averageDepth >= center.z - size * 0.006,
16516
- baseWidth: size *
16517
- (0.019 +
16518
- morphologyProfile.tentacles.baseWidthScale * 0.007 +
16519
- tentacleRandom() * 0.003 +
16520
- Math.abs(Math.sin(orbitAngle)) * 0.002),
16521
- tipWidth: size * (0.0046 + morphologyProfile.tentacles.tipWidthScale * 0.0018),
16522
- colorBias: tentacleRandom(),
16523
- };
16524
- });
16525
- }
16526
- /**
16527
- * Samples one point on a cubic Bezier curve in 3D.
16528
- *
16529
- * @private helper of `octopus3dAvatarVisual`
16530
- */
16531
- function sampleCubicBezierPoint3D(startPoint, controlPointOne, controlPointTwo, endPoint, progress) {
16532
- const inverseProgress = 1 - progress;
16533
- return {
16534
- x: inverseProgress * inverseProgress * inverseProgress * startPoint.x +
16535
- 3 * inverseProgress * inverseProgress * progress * controlPointOne.x +
16536
- 3 * inverseProgress * progress * progress * controlPointTwo.x +
16537
- progress * progress * progress * endPoint.x,
16538
- y: inverseProgress * inverseProgress * inverseProgress * startPoint.y +
16539
- 3 * inverseProgress * inverseProgress * progress * controlPointOne.y +
16540
- 3 * inverseProgress * progress * progress * controlPointTwo.y +
16541
- progress * progress * progress * endPoint.y,
16542
- z: inverseProgress * inverseProgress * inverseProgress * startPoint.z +
16543
- 3 * inverseProgress * inverseProgress * progress * controlPointOne.z +
16544
- 3 * inverseProgress * progress * progress * controlPointTwo.z +
16545
- progress * progress * progress * endPoint.z,
16546
- };
16547
- }
16548
- /**
16549
- * Draws one projected tentacle stroke with a slim highlight ridge.
16550
- *
16551
- * @private helper of `octopus3dAvatarVisual`
16552
- */
16553
- function drawTentacleStroke(context, tentacleStroke, palette) {
16554
- const projectedSegments = tentacleStroke.projectedPoints.length - 1;
16555
- for (let segmentIndex = 0; segmentIndex < projectedSegments; segmentIndex++) {
16556
- const startPoint = tentacleStroke.projectedPoints[segmentIndex];
16557
- const endPoint = tentacleStroke.projectedPoints[segmentIndex + 1];
16558
- const progress = segmentIndex / projectedSegments;
16559
- const width = tentacleStroke.baseWidth + (tentacleStroke.tipWidth - tentacleStroke.baseWidth) * progress;
16560
- context.beginPath();
16561
- context.moveTo(startPoint.x, startPoint.y);
16562
- context.lineTo(endPoint.x, endPoint.y);
16563
- context.strokeStyle = tentacleStroke.colorBias > 0.6 ? `${palette.secondary}f0` : `${palette.primary}f0`;
16564
- context.lineWidth = width;
16565
- context.lineCap = 'round';
16566
- context.stroke();
16567
- context.beginPath();
16568
- context.moveTo(startPoint.x, startPoint.y);
16569
- context.lineTo(endPoint.x, endPoint.y);
16570
- context.strokeStyle = tentacleStroke.isFrontFacing ? `${palette.highlight}80` : `${palette.highlight}40`;
16571
- context.lineWidth = Math.max(1, width * 0.34);
16572
- context.lineCap = 'round';
16573
- context.stroke();
16574
- }
16575
- }
16576
- /**
16577
- * Resolves the front surface depth on an ellipsoid for one local face point.
16578
- *
16579
- * @private helper of `octopus3dAvatarVisual`
16580
- */
16581
- function resolveEllipsoidSurfaceDepth(radiusX, radiusY, radiusZ, x, y) {
16582
- const normalizedX = x / radiusX;
16583
- const normalizedY = y / radiusY;
16584
- const remainingDepthRatio = Math.max(0, 1 - normalizedX * normalizedX - normalizedY * normalizedY);
16585
- return Math.sqrt(remainingDepthRatio) * radiusZ;
16586
- }
16587
-
16588
16186
  /* eslint-disable no-magic-numbers */
16589
16187
  /**
16590
16188
  * Light direction used by the single-mesh octopus shading.
16591
16189
  *
16592
16190
  * @private helper of `octopus3d2AvatarVisual`
16593
16191
  */
16594
- const LIGHT_DIRECTION$2 = normalizeVector3({
16192
+ const LIGHT_DIRECTION$3 = normalizeVector3({
16595
16193
  x: 0.38,
16596
16194
  y: -0.6,
16597
16195
  z: 0.98,
@@ -16830,7 +16428,7 @@ function resolveVisibleBlobbyOctopusPatches(options) {
16830
16428
  transformedCorners[2].z +
16831
16429
  transformedCorners[3].z) /
16832
16430
  4,
16833
- lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$2), -1, 1),
16431
+ lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$3), -1, 1),
16834
16432
  fillStyle: resolveBlobbySurfacePatchFillStyle$1(palette, verticalProgress, Math.max(0, Math.cos(centerLongitude)), resolveLowerLobeWave(centerLongitude, morphologyProfile, animationPhase, timeMs)),
16835
16433
  outlineColor: verticalProgress < 0.58 ? `${palette.highlight}73` : `${palette.shadow}8a`,
16836
16434
  });
@@ -16945,7 +16543,7 @@ function drawBlobbySurfacePatch(context, surfacePatch) {
16945
16543
  *
16946
16544
  * @private helper of `octopus3d3AvatarVisual`
16947
16545
  */
16948
- const LIGHT_DIRECTION$1 = normalizeVector3({
16546
+ const LIGHT_DIRECTION$2 = normalizeVector3({
16949
16547
  x: 0.34,
16950
16548
  y: -0.62,
16951
16549
  z: 1,
@@ -17252,7 +16850,7 @@ function resolveVisibleContinuousOctopusPatches(options) {
17252
16850
  transformedCorners[2].z +
17253
16851
  transformedCorners[3].z) /
17254
16852
  4,
17255
- lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$1), -1, 1),
16853
+ lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$2), -1, 1),
17256
16854
  fillStyle: resolveContinuousSurfacePatchFillStyle(palette, verticalProgress, cachedCosByPatchCenterLongitude[longitudeIndex], cachedTentacleInfluencesByPatchCenterLongitude[longitudeIndex].core, cachedLobeWavesByPatchCenterLongitude[longitudeIndex]),
17257
16855
  outlineColor: verticalProgress < 0.54 ? `${palette.highlight}69` : `${palette.shadow}78`,
17258
16856
  });
@@ -17567,7 +17165,7 @@ function smoothStep$1(edgeStart, edgeEnd, value) {
17567
17165
  *
17568
17166
  * @private helper of `octopus3d4AvatarVisual`
17569
17167
  */
17570
- const LIGHT_DIRECTION = normalizeVector3({
17168
+ const LIGHT_DIRECTION$1 = normalizeVector3({
17571
17169
  x: 0.32,
17572
17170
  y: -0.66,
17573
17171
  z: 1,
@@ -17913,7 +17511,7 @@ function resolveVisibleBlobbyContinuousPatches(options) {
17913
17511
  projectScenePoint(transformedCorners[2], size, sceneCenterX, sceneCenterY),
17914
17512
  projectScenePoint(transformedCorners[3], size, sceneCenterX, sceneCenterY),
17915
17513
  ];
17916
- const lightIntensity = clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION), -1, 1);
17514
+ const lightIntensity = clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$1), -1, 1);
17917
17515
  const rimLightIntensity = Math.pow(clampNumber$1(dotProduct3D(surfaceNormal, RIM_LIGHT_DIRECTION), 0, 1), 2.6);
17918
17516
  surfacePatches.push({
17919
17517
  corners: projectedCorners,
@@ -18312,6 +17910,445 @@ function formatAlphaHex(opacity) {
18312
17910
  .padStart(2, '0');
18313
17911
  }
18314
17912
 
17913
+ /* eslint-disable no-magic-numbers */
17914
+ /**
17915
+ * Light direction used by the organic 3D octopus shading.
17916
+ *
17917
+ * @private helper of `octopus3dAvatarVisual`
17918
+ */
17919
+ const LIGHT_DIRECTION = normalizeVector3({
17920
+ x: 0.48,
17921
+ y: -0.62,
17922
+ z: 0.94,
17923
+ });
17924
+ /**
17925
+ * Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
17926
+ *
17927
+ * @private helper of `octopus3dAvatarVisual`
17928
+ */
17929
+ const octopus3dStableStateCache = new WeakMap();
17930
+ /**
17931
+ * Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
17932
+ *
17933
+ * @private helper of `octopus3dAvatarVisual`
17934
+ */
17935
+ function getOctopus3dStableState(createRandom) {
17936
+ const cached = octopus3dStableStateCache.get(createRandom);
17937
+ if (cached !== undefined) {
17938
+ return cached;
17939
+ }
17940
+ const animationRandom = createRandom('octopus3d-animation-profile');
17941
+ const eyeRandom = createRandom('octopus3d-eye-profile');
17942
+ const leftEyePhaseOffset = eyeRandom() * 0.6;
17943
+ const rightEyePhaseOffset = eyeRandom() * 0.6;
17944
+ const state = {
17945
+ morphologyProfile: createOctopus3MorphologyProfile(createRandom),
17946
+ animationPhase: animationRandom() * Math.PI * 2,
17947
+ leftEyePhaseOffset,
17948
+ rightEyePhaseOffset,
17949
+ };
17950
+ octopus3dStableStateCache.set(createRandom, state);
17951
+ return state;
17952
+ }
17953
+ /**
17954
+ * Proper 3D Octopus visual built from projected organic meshes and tentacles.
17955
+ *
17956
+ * @private built-in avatar visual
17957
+ */
17958
+ const octopus3dAvatarVisual = {
17959
+ id: 'octopus3d',
17960
+ title: 'Octopus 3D',
17961
+ description: 'Proper 3D octopus portrait with a turning silhouette, expressive eyes, and depth-sorted tentacles.',
17962
+ isAnimated: true,
17963
+ supportsPointerTracking: true,
17964
+ render({ context, size, palette, createRandom, timeMs, interaction }) {
17965
+ const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3dStableState(createRandom);
17966
+ const sceneCenterX = size * 0.5;
17967
+ const sceneCenterY = size * 0.56;
17968
+ const bob = Math.sin(timeMs / 920 + animationPhase) * size * 0.014;
17969
+ const mantleCenter = {
17970
+ x: interaction.bodyOffsetX * size * 0.042 + size * morphologyProfile.body.centerXJitterRatio * 0.65,
17971
+ y: -size * 0.09 + interaction.bodyOffsetY * size * 0.028 + bob,
17972
+ z: interaction.intensity * size * 0.012,
17973
+ };
17974
+ const underbodyCenter = {
17975
+ x: mantleCenter.x * 0.86,
17976
+ y: mantleCenter.y + size * 0.168,
17977
+ z: mantleCenter.z - size * 0.018,
17978
+ };
17979
+ const mantleRadiusX = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.horizontalStretch;
17980
+ const mantleRadiusY = size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.verticalStretch * 1.1;
17981
+ const mantleRadiusZ = size *
17982
+ morphologyProfile.body.bodyRadiusRatio *
17983
+ (0.9 + (morphologyProfile.body.horizontalStretch - 1) * 0.3);
17984
+ const underbodyRadiusX = mantleRadiusX * (0.9 + (morphologyProfile.tentacles.rootSpreadScale - 1) * 0.08);
17985
+ const underbodyRadiusY = mantleRadiusY * (0.44 + morphologyProfile.body.lowerDropRatio * 3.1);
17986
+ const underbodyRadiusZ = mantleRadiusZ * 0.78;
17987
+ const bodyYaw = -0.18 +
17988
+ Math.sin(timeMs / 2400 + animationPhase) * 0.05 +
17989
+ interaction.bodyOffsetX * 0.18 +
17990
+ interaction.gazeX * 0.22;
17991
+ const bodyPitch = -0.08 +
17992
+ Math.cos(timeMs / 2700 + animationPhase * 0.6) * 0.025 -
17993
+ interaction.bodyOffsetY * 0.08 -
17994
+ interaction.gazeY * 0.08;
17995
+ const headYaw = bodyYaw - 0.04 + interaction.gazeX * 0.56;
17996
+ const headPitch = bodyPitch - 0.02 - interaction.gazeY * 0.32;
17997
+ const mantlePatches = resolveVisibleEllipsoidPatches({
17998
+ center: mantleCenter,
17999
+ radiusX: mantleRadiusX,
18000
+ radiusY: mantleRadiusY,
18001
+ radiusZ: mantleRadiusZ,
18002
+ rotationX: headPitch,
18003
+ rotationY: headYaw,
18004
+ sceneCenterX,
18005
+ sceneCenterY,
18006
+ size,
18007
+ palette,
18008
+ verticalColorBias: 0,
18009
+ outlineColor: `${palette.highlight}7a`,
18010
+ });
18011
+ const underbodyPatches = resolveVisibleEllipsoidPatches({
18012
+ center: underbodyCenter,
18013
+ radiusX: underbodyRadiusX,
18014
+ radiusY: underbodyRadiusY,
18015
+ radiusZ: underbodyRadiusZ,
18016
+ rotationX: bodyPitch,
18017
+ rotationY: bodyYaw,
18018
+ sceneCenterX,
18019
+ sceneCenterY,
18020
+ size,
18021
+ palette,
18022
+ verticalColorBias: 0.18,
18023
+ outlineColor: `${palette.shadow}8f`,
18024
+ });
18025
+ const tentacleStrokes = createOctopusTentacleStrokes({
18026
+ createRandom,
18027
+ morphologyProfile,
18028
+ timeMs,
18029
+ size,
18030
+ center: underbodyCenter,
18031
+ radiusX: underbodyRadiusX,
18032
+ radiusY: underbodyRadiusY,
18033
+ radiusZ: underbodyRadiusZ,
18034
+ rotationX: bodyPitch,
18035
+ rotationY: bodyYaw,
18036
+ sceneCenterX,
18037
+ sceneCenterY,
18038
+ animationPhase,
18039
+ });
18040
+ const faceEyeSpacing = size * morphologyProfile.face.eyeSpacingRatio * 0.92;
18041
+ const faceEyeYOffset = size * morphologyProfile.face.eyeCenterYOffsetRatio - mantleRadiusY * 0.02;
18042
+ const faceEyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio * 0.82;
18043
+ const faceEyeRadiusY = faceEyeRadiusX * morphologyProfile.face.eyeHeightRatio * 0.96;
18044
+ const mouthHalfWidth = size * morphologyProfile.face.mouthWidthRatio * 0.92;
18045
+ const mouthY = size * morphologyProfile.face.mouthYOffsetRatio + mantleRadiusY * 0.08;
18046
+ drawAvatarFrame(context, size, palette);
18047
+ drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs);
18048
+ drawOctopus3dShadow(context, size, palette, interaction, timeMs);
18049
+ for (const tentacleStroke of tentacleStrokes.filter((candidateTentacleStroke) => !candidateTentacleStroke.isFrontFacing)) {
18050
+ drawTentacleStroke(context, tentacleStroke, palette);
18051
+ }
18052
+ for (const surfacePatch of [...mantlePatches, ...underbodyPatches].sort((firstSurfacePatch, secondSurfacePatch) => firstSurfacePatch.averageDepth - secondSurfacePatch.averageDepth)) {
18053
+ drawSurfacePatch(context, surfacePatch);
18054
+ }
18055
+ for (const tentacleStroke of tentacleStrokes.filter((candidateTentacleStroke) => candidateTentacleStroke.isFrontFacing)) {
18056
+ drawTentacleStroke(context, tentacleStroke, palette);
18057
+ }
18058
+ drawProjectedOrganicEye(context, {
18059
+ x: -faceEyeSpacing,
18060
+ y: faceEyeYOffset,
18061
+ z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -faceEyeSpacing, faceEyeYOffset),
18062
+ }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
18063
+ drawProjectedOrganicEye(context, {
18064
+ x: faceEyeSpacing,
18065
+ y: faceEyeYOffset,
18066
+ z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
18067
+ }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
18068
+ drawProjectedOrganicMouth(context, [
18069
+ {
18070
+ x: -mouthHalfWidth,
18071
+ y: mouthY,
18072
+ z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -mouthHalfWidth, mouthY),
18073
+ },
18074
+ {
18075
+ x: size * morphologyProfile.face.mouthCenterOffsetRatio,
18076
+ y: mouthY +
18077
+ size * morphologyProfile.face.mouthCurveDepthRatio * 0.38 +
18078
+ Math.sin(timeMs / 760 + animationPhase) * size * 0.01 +
18079
+ interaction.gazeY * size * 0.01,
18080
+ z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, size * morphologyProfile.face.mouthCenterOffsetRatio, mouthY),
18081
+ },
18082
+ {
18083
+ x: mouthHalfWidth,
18084
+ y: mouthY,
18085
+ z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, mouthHalfWidth, mouthY),
18086
+ },
18087
+ ], mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, palette, size);
18088
+ },
18089
+ };
18090
+ /**
18091
+ * Draws the atmospheric underwater glow behind the octopus mesh.
18092
+ *
18093
+ * @private helper of `octopus3dAvatarVisual`
18094
+ */
18095
+ function drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs) {
18096
+ 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);
18097
+ glowGradient.addColorStop(0, `${palette.highlight}5c`);
18098
+ glowGradient.addColorStop(0.36, `${palette.accent}24`);
18099
+ glowGradient.addColorStop(1, `${palette.highlight}00`);
18100
+ context.fillStyle = glowGradient;
18101
+ context.fillRect(0, 0, size, size);
18102
+ 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);
18103
+ lowerGradient.addColorStop(0, `${palette.secondary}1d`);
18104
+ lowerGradient.addColorStop(1, `${palette.secondary}00`);
18105
+ context.fillStyle = lowerGradient;
18106
+ context.fillRect(0, 0, size, size);
18107
+ }
18108
+ /**
18109
+ * Draws the soft ground shadow below the octopus.
18110
+ *
18111
+ * Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
18112
+ * blurry ellipse without triggering a costly software rasterization pass on every frame.
18113
+ *
18114
+ * @private helper of `octopus3dAvatarVisual`
18115
+ */
18116
+ function drawOctopus3dShadow(context, size, palette, interaction, timeMs) {
18117
+ const cx = size * 0.5 + interaction.gazeX * size * 0.04;
18118
+ const cy = size * 0.87 + Math.sin(timeMs / 920) * size * 0.008;
18119
+ const rx = size * (0.18 + interaction.intensity * 0.02);
18120
+ const ry = size * 0.06;
18121
+ context.save();
18122
+ context.translate(cx, cy);
18123
+ context.scale(1, ry / rx);
18124
+ const blurRadius = rx * 1.4;
18125
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
18126
+ shadowGradient.addColorStop(0, `${palette.shadow}7a`);
18127
+ shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
18128
+ shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
18129
+ shadowGradient.addColorStop(1, `${palette.shadow}00`);
18130
+ context.fillStyle = shadowGradient;
18131
+ context.beginPath();
18132
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
18133
+ context.fill();
18134
+ context.restore();
18135
+ }
18136
+ /**
18137
+ * Resolves visible projected patches for one rotated ellipsoid mesh.
18138
+ *
18139
+ * @private helper of `octopus3dAvatarVisual`
18140
+ */
18141
+ function resolveVisibleEllipsoidPatches(options) {
18142
+ const { center, radiusX, radiusY, radiusZ, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, verticalColorBias, outlineColor, } = options;
18143
+ const latitudePatchCount = 10;
18144
+ const longitudePatchCount = 18;
18145
+ const surfacePatches = [];
18146
+ for (let latitudeIndex = 0; latitudeIndex < latitudePatchCount; latitudeIndex++) {
18147
+ const startLatitude = -Math.PI / 2 + (latitudeIndex / latitudePatchCount) * Math.PI;
18148
+ const endLatitude = -Math.PI / 2 + ((latitudeIndex + 1) / latitudePatchCount) * Math.PI;
18149
+ const verticalProgress = (latitudeIndex + 0.5) / latitudePatchCount;
18150
+ for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
18151
+ const startLongitude = -Math.PI + (longitudeIndex / longitudePatchCount) * Math.PI * 2;
18152
+ const endLongitude = -Math.PI + ((longitudeIndex + 1) / longitudePatchCount) * Math.PI * 2;
18153
+ const localCorners = [
18154
+ sampleEllipsoidPoint(radiusX, radiusY, radiusZ, startLatitude, startLongitude),
18155
+ sampleEllipsoidPoint(radiusX, radiusY, radiusZ, startLatitude, endLongitude),
18156
+ sampleEllipsoidPoint(radiusX, radiusY, radiusZ, endLatitude, endLongitude),
18157
+ sampleEllipsoidPoint(radiusX, radiusY, radiusZ, endLatitude, startLongitude),
18158
+ ];
18159
+ const transformedCorners = localCorners.map((localCorner) => transformScenePoint(localCorner, center, rotationX, rotationY));
18160
+ const surfaceNormal = normalizeVector3(crossProduct3D(subtractPoint3D(transformedCorners[1], transformedCorners[0]), subtractPoint3D(transformedCorners[2], transformedCorners[0])));
18161
+ if (surfaceNormal.z <= 0.01) {
18162
+ continue;
18163
+ }
18164
+ const projectedCorners = transformedCorners.map((transformedCorner) => projectScenePoint(transformedCorner, size, sceneCenterX, sceneCenterY));
18165
+ surfacePatches.push({
18166
+ corners: projectedCorners,
18167
+ averageDepth: transformedCorners.reduce((depthSum, transformedCorner) => depthSum + transformedCorner.z, 0) /
18168
+ transformedCorners.length,
18169
+ lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION), -1, 1),
18170
+ fillStyle: resolveSurfacePatchFillStyle(palette, verticalProgress + verticalColorBias),
18171
+ outlineColor,
18172
+ });
18173
+ }
18174
+ }
18175
+ return surfacePatches;
18176
+ }
18177
+ /**
18178
+ * Samples one point on an ellipsoid aligned to the local axes.
18179
+ *
18180
+ * @private helper of `octopus3dAvatarVisual`
18181
+ */
18182
+ function sampleEllipsoidPoint(radiusX, radiusY, radiusZ, latitude, longitude) {
18183
+ const cosineLatitude = Math.cos(latitude);
18184
+ return {
18185
+ x: Math.sin(longitude) * cosineLatitude * radiusX,
18186
+ y: Math.sin(latitude) * radiusY,
18187
+ z: Math.cos(longitude) * cosineLatitude * radiusZ,
18188
+ };
18189
+ }
18190
+ /**
18191
+ * Resolves one base fill tone for a surface patch across the octopus body.
18192
+ *
18193
+ * @private helper of `octopus3dAvatarVisual`
18194
+ */
18195
+ function resolveSurfacePatchFillStyle(palette, verticalProgress) {
18196
+ const clampedVerticalProgress = clampNumber$1(verticalProgress, 0, 1);
18197
+ if (clampedVerticalProgress < 0.2) {
18198
+ return palette.highlight;
18199
+ }
18200
+ if (clampedVerticalProgress < 0.45) {
18201
+ return palette.secondary;
18202
+ }
18203
+ if (clampedVerticalProgress < 0.8) {
18204
+ return palette.primary;
18205
+ }
18206
+ return `${palette.shadow}f2`;
18207
+ }
18208
+ /**
18209
+ * Draws one projected mesh patch with organic shading.
18210
+ *
18211
+ * @private helper of `octopus3dAvatarVisual`
18212
+ */
18213
+ function drawSurfacePatch(context, surfacePatch) {
18214
+ drawProjectedQuad(context, surfacePatch.corners, surfacePatch.fillStyle);
18215
+ if (surfacePatch.lightIntensity > 0) {
18216
+ drawProjectedQuad(context, surfacePatch.corners, `rgba(255, 255, 255, ${0.15 * surfacePatch.lightIntensity})`);
18217
+ }
18218
+ else if (surfacePatch.lightIntensity < 0) {
18219
+ drawProjectedQuad(context, surfacePatch.corners, `rgba(0, 0, 0, ${0.24 * Math.abs(surfacePatch.lightIntensity)})`);
18220
+ }
18221
+ context.save();
18222
+ context.beginPath();
18223
+ context.moveTo(surfacePatch.corners[0].x, surfacePatch.corners[0].y);
18224
+ for (let cornerIndex = 1; cornerIndex < surfacePatch.corners.length; cornerIndex++) {
18225
+ context.lineTo(surfacePatch.corners[cornerIndex].x, surfacePatch.corners[cornerIndex].y);
18226
+ }
18227
+ context.closePath();
18228
+ context.strokeStyle = surfacePatch.outlineColor;
18229
+ context.lineWidth = Math.max(1, getProjectedQuadPerimeter(surfacePatch.corners) * 0.0044);
18230
+ context.lineJoin = 'round';
18231
+ context.stroke();
18232
+ context.restore();
18233
+ }
18234
+ /**
18235
+ * Creates the projected 3D tentacle strokes orbiting around the lower octopus body.
18236
+ *
18237
+ * @private helper of `octopus3dAvatarVisual`
18238
+ */
18239
+ function createOctopusTentacleStrokes(options) {
18240
+ const { createRandom, morphologyProfile, timeMs, size, center, radiusX, radiusY, radiusZ, rotationX, rotationY, sceneCenterX, sceneCenterY, animationPhase, } = options;
18241
+ return Array.from({ length: morphologyProfile.tentacles.count }, (_, tentacleIndex) => {
18242
+ const tentacleRandom = createRandom(`octopus3d-tentacle-${tentacleIndex}`);
18243
+ const spreadProgress = morphologyProfile.tentacles.count === 1 ? 0.5 : tentacleIndex / (morphologyProfile.tentacles.count - 1);
18244
+ const orbitAngle = -Math.PI * 0.92 + spreadProgress * Math.PI * 1.84 + (tentacleRandom() - 0.5) * 0.16;
18245
+ const flowLength = size * (0.19 + morphologyProfile.tentacles.flowLengthScale * 0.075 + tentacleRandom() * 0.018);
18246
+ const lateralReach = size *
18247
+ (0.08 + morphologyProfile.tentacles.lateralReachScale * 0.05 + Math.abs(Math.sin(orbitAngle)) * 0.018);
18248
+ const depthReach = size * (0.028 + morphologyProfile.tentacles.tipReachScale * 0.032);
18249
+ const sway = Math.sin(timeMs / (760 + tentacleIndex * 36) + animationPhase + tentacleRandom() * Math.PI * 2);
18250
+ const anchorPoint = {
18251
+ x: Math.sin(orbitAngle) * radiusX * (0.84 + tentacleRandom() * 0.08),
18252
+ y: radiusY * (0.22 + tentacleRandom() * 0.18),
18253
+ z: Math.cos(orbitAngle) * radiusZ * (0.72 + tentacleRandom() * 0.12),
18254
+ };
18255
+ const controlPointOne = {
18256
+ x: anchorPoint.x + Math.sin(orbitAngle) * lateralReach * 0.44,
18257
+ y: anchorPoint.y + flowLength * 0.26,
18258
+ z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.3 + sway * size * 0.012,
18259
+ };
18260
+ const controlPointTwo = {
18261
+ x: anchorPoint.x +
18262
+ Math.sin(orbitAngle) * lateralReach * (0.82 + morphologyProfile.tentacles.swayScale * 0.12),
18263
+ y: anchorPoint.y + flowLength * 0.66,
18264
+ z: anchorPoint.z + Math.cos(orbitAngle) * depthReach * 0.72 + sway * size * 0.02,
18265
+ };
18266
+ const endPoint = {
18267
+ x: anchorPoint.x +
18268
+ Math.sin(orbitAngle) * lateralReach * (1.02 + morphologyProfile.tentacles.tipWidthScale * 0.12) +
18269
+ sway * size * 0.028,
18270
+ y: anchorPoint.y + flowLength,
18271
+ z: anchorPoint.z + Math.cos(orbitAngle) * depthReach + sway * size * 0.016,
18272
+ };
18273
+ const scenePoints = Array.from({ length: 12 }, (_, sampleIndex) => transformScenePoint(sampleCubicBezierPoint3D(anchorPoint, controlPointOne, controlPointTwo, endPoint, sampleIndex / 11), center, rotationX, rotationY));
18274
+ const projectedPoints = scenePoints.map((scenePoint) => projectScenePoint(scenePoint, size, sceneCenterX, sceneCenterY));
18275
+ const averageDepth = scenePoints.reduce((depthSum, scenePoint) => depthSum + scenePoint.z, 0) / scenePoints.length;
18276
+ return {
18277
+ projectedPoints,
18278
+ averageDepth,
18279
+ isFrontFacing: averageDepth >= center.z - size * 0.006,
18280
+ baseWidth: size *
18281
+ (0.019 +
18282
+ morphologyProfile.tentacles.baseWidthScale * 0.007 +
18283
+ tentacleRandom() * 0.003 +
18284
+ Math.abs(Math.sin(orbitAngle)) * 0.002),
18285
+ tipWidth: size * (0.0046 + morphologyProfile.tentacles.tipWidthScale * 0.0018),
18286
+ colorBias: tentacleRandom(),
18287
+ };
18288
+ });
18289
+ }
18290
+ /**
18291
+ * Samples one point on a cubic Bezier curve in 3D.
18292
+ *
18293
+ * @private helper of `octopus3dAvatarVisual`
18294
+ */
18295
+ function sampleCubicBezierPoint3D(startPoint, controlPointOne, controlPointTwo, endPoint, progress) {
18296
+ const inverseProgress = 1 - progress;
18297
+ return {
18298
+ x: inverseProgress * inverseProgress * inverseProgress * startPoint.x +
18299
+ 3 * inverseProgress * inverseProgress * progress * controlPointOne.x +
18300
+ 3 * inverseProgress * progress * progress * controlPointTwo.x +
18301
+ progress * progress * progress * endPoint.x,
18302
+ y: inverseProgress * inverseProgress * inverseProgress * startPoint.y +
18303
+ 3 * inverseProgress * inverseProgress * progress * controlPointOne.y +
18304
+ 3 * inverseProgress * progress * progress * controlPointTwo.y +
18305
+ progress * progress * progress * endPoint.y,
18306
+ z: inverseProgress * inverseProgress * inverseProgress * startPoint.z +
18307
+ 3 * inverseProgress * inverseProgress * progress * controlPointOne.z +
18308
+ 3 * inverseProgress * progress * progress * controlPointTwo.z +
18309
+ progress * progress * progress * endPoint.z,
18310
+ };
18311
+ }
18312
+ /**
18313
+ * Draws one projected tentacle stroke with a slim highlight ridge.
18314
+ *
18315
+ * @private helper of `octopus3dAvatarVisual`
18316
+ */
18317
+ function drawTentacleStroke(context, tentacleStroke, palette) {
18318
+ const projectedSegments = tentacleStroke.projectedPoints.length - 1;
18319
+ for (let segmentIndex = 0; segmentIndex < projectedSegments; segmentIndex++) {
18320
+ const startPoint = tentacleStroke.projectedPoints[segmentIndex];
18321
+ const endPoint = tentacleStroke.projectedPoints[segmentIndex + 1];
18322
+ const progress = segmentIndex / projectedSegments;
18323
+ const width = tentacleStroke.baseWidth + (tentacleStroke.tipWidth - tentacleStroke.baseWidth) * progress;
18324
+ context.beginPath();
18325
+ context.moveTo(startPoint.x, startPoint.y);
18326
+ context.lineTo(endPoint.x, endPoint.y);
18327
+ context.strokeStyle = tentacleStroke.colorBias > 0.6 ? `${palette.secondary}f0` : `${palette.primary}f0`;
18328
+ context.lineWidth = width;
18329
+ context.lineCap = 'round';
18330
+ context.stroke();
18331
+ context.beginPath();
18332
+ context.moveTo(startPoint.x, startPoint.y);
18333
+ context.lineTo(endPoint.x, endPoint.y);
18334
+ context.strokeStyle = tentacleStroke.isFrontFacing ? `${palette.highlight}80` : `${palette.highlight}40`;
18335
+ context.lineWidth = Math.max(1, width * 0.34);
18336
+ context.lineCap = 'round';
18337
+ context.stroke();
18338
+ }
18339
+ }
18340
+ /**
18341
+ * Resolves the front surface depth on an ellipsoid for one local face point.
18342
+ *
18343
+ * @private helper of `octopus3dAvatarVisual`
18344
+ */
18345
+ function resolveEllipsoidSurfaceDepth(radiusX, radiusY, radiusZ, x, y) {
18346
+ const normalizedX = x / radiusX;
18347
+ const normalizedY = y / radiusY;
18348
+ const remainingDepthRatio = Math.max(0, 1 - normalizedX * normalizedX - normalizedY * normalizedY);
18349
+ return Math.sqrt(remainingDepthRatio) * radiusZ;
18350
+ }
18351
+
18315
18352
  /* eslint-disable no-magic-numbers */
18316
18353
  /**
18317
18354
  * Octopus avatar visual.
@@ -19132,14 +19169,14 @@ function resolveAvatarVisualId(value) {
19132
19169
  /**
19133
19170
  * META AVATAR commitment definition
19134
19171
  *
19135
- * The `META AVATAR` commitment sets the built-in default avatar visual used when
19136
- * the agent does not provide an explicit `META IMAGE`.
19172
+ * The `META AVATAR` and `META VISUAL` commitments set the built-in default avatar visual
19173
+ * used when the agent does not provide an explicit `META IMAGE`.
19137
19174
  *
19138
19175
  * @private [🪔] Maybe export the commitments through some package
19139
19176
  */
19140
19177
  class MetaAvatarCommitmentDefinition extends BaseCommitmentDefinition {
19141
- constructor() {
19142
- super('META AVATAR');
19178
+ constructor(type = 'META AVATAR') {
19179
+ super(type);
19143
19180
  }
19144
19181
  /**
19145
19182
  * Short one-line description of META AVATAR.
@@ -19159,14 +19196,15 @@ class MetaAvatarCommitmentDefinition extends BaseCommitmentDefinition {
19159
19196
  get documentation() {
19160
19197
  const supportedVisuals = AVATAR_VISUALS.map((avatarVisual) => `\`${avatarVisual.id}\``).join(', ');
19161
19198
  return spaceTrim$1(`
19162
- # META AVATAR
19199
+ # ${this.type}
19163
19200
 
19164
19201
  Sets the built-in avatar visual used for the agent when no explicit \`META IMAGE\` is provided.
19202
+ \`META AVATAR\` and \`META VISUAL\` are equivalent.
19165
19203
 
19166
19204
  ## Key aspects
19167
19205
 
19168
19206
  - Does not modify the agent's behavior or responses.
19169
- - Only one \`META AVATAR\` should be used per agent.
19207
+ - Only one \`META AVATAR\` or \`META VISUAL\` should be used per agent.
19170
19208
  - If multiple are specified, the last one takes precedence.
19171
19209
  - Values are matched case-insensitively and spaces, hyphens, and underscores are normalized.
19172
19210
  - Supported visuals are derived from the shared avatar registry: ${supportedVisuals}.
@@ -19181,15 +19219,15 @@ class MetaAvatarCommitmentDefinition extends BaseCommitmentDefinition {
19181
19219
  \`\`\`
19182
19220
 
19183
19221
  \`\`\`book
19184
- Orb Assistant
19222
+ Minecraft Assistant
19185
19223
 
19186
- META AVATAR orb
19224
+ META VISUAL Minecraft2
19187
19225
  GOAL Answer in a calm and focused way.
19188
19226
  \`\`\`
19189
19227
  `);
19190
19228
  }
19191
19229
  applyToAgentModelRequirements(requirements, content) {
19192
- // META AVATAR doesn't modify the system message or model requirements.
19230
+ // META AVATAR and META VISUAL don't modify the system message or model requirements.
19193
19231
  // It's handled separately in the parsing logic for profile avatar resolution.
19194
19232
  return requirements;
19195
19233
  }
@@ -28540,6 +28578,7 @@ const COMMITMENT_REGISTRY = [
28540
28578
  new ActionCommitmentDefinition('ACTIONS'),
28541
28579
  new ComponentCommitmentDefinition(),
28542
28580
  new MetaAvatarCommitmentDefinition(),
28581
+ new MetaAvatarCommitmentDefinition('META VISUAL'),
28543
28582
  new MetaImageCommitmentDefinition(),
28544
28583
  new MetaColorCommitmentDefinition(),
28545
28584
  new MetaFontCommitmentDefinition(),
@@ -33580,6 +33619,7 @@ function hasHttpProtocol(value) {
33580
33619
  */
33581
33620
  const META_COMMITMENT_APPLIERS = {
33582
33621
  'META AVATAR': applyMetaAvatarContent,
33622
+ 'META VISUAL': applyMetaAvatarContent,
33583
33623
  'META LINK': applyMetaLinkContent,
33584
33624
  'META DOMAIN': applyMetaDomainContent,
33585
33625
  'META IMAGE': applyMetaImageContent,
@@ -33628,7 +33668,7 @@ function applyGenericMetaCommitment(state, content) {
33628
33668
  state.meta[metaType] = metaValue;
33629
33669
  }
33630
33670
  /**
33631
- * Applies META AVATAR content into the canonical `meta.avatar` field.
33671
+ * Applies META AVATAR / META VISUAL content into the canonical `meta.avatar` field.
33632
33672
  */
33633
33673
  function applyMetaAvatarContent(state, content) {
33634
33674
  const avatarVisualId = resolveAvatarVisualId(content);