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