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