@promptbook/remote-server 0.113.0-0 → 0.113.0-10

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