diff --git a/lib/agents/workflow-ui-config.ts b/lib/agents/workflow-ui-config.ts index c0e41ebd2..fad7e9ea4 100644 --- a/lib/agents/workflow-ui-config.ts +++ b/lib/agents/workflow-ui-config.ts @@ -658,6 +658,7 @@ export function getRenderableAgentWorkflowOptionTree( const nextOptions = [...options] .sort((left, right) => left.sortOrder - right.sortOrder) + .filter((option) => hasAgentWorkflowOptionRenderablePreview(option)) .map((option) => ({ ...option, children: getRenderableAgentWorkflowOptionTree(option.children || []), @@ -806,6 +807,37 @@ export function hasAgentWorkflowOptionOwnPreview( ); } +function getFirstAgentWorkflowOptionPreview( + option: AgentWorkflowOptionUiConfig +): { previewImageUrl: string; previewImageSourceUrl: string } | null { + const ownPreviewImageUrl = String(option.previewImageUrl || "").trim(); + const ownPreviewImageSourceUrl = String(option.previewImageSourceUrl || "").trim(); + if (ownPreviewImageUrl || ownPreviewImageSourceUrl) { + return { + previewImageUrl: ownPreviewImageUrl || ownPreviewImageSourceUrl, + previewImageSourceUrl: ownPreviewImageSourceUrl || ownPreviewImageUrl, + }; + } + + for (const child of option.children || []) { + if (child.enabled === false) { + continue; + } + const childPreview = getFirstAgentWorkflowOptionPreview(child); + if (childPreview) { + return childPreview; + } + } + + return null; +} + +function hasAgentWorkflowOptionRenderablePreview( + option: AgentWorkflowOptionUiConfig +): boolean { + return Boolean(getFirstAgentWorkflowOptionPreview(option)); +} + export function getAgentWorkflowMissingPreviewOptions( steps: AgentWorkflowStepUiConfig[], options: { enabledOnly?: boolean } = {} @@ -895,6 +927,7 @@ export function getEnabledAgentWorkflowOptionTree( const nextOptions = [...options] .sort((left, right) => left.sortOrder - right.sortOrder) .filter((option) => option.enabled !== false) + .filter((option) => hasAgentWorkflowOptionRenderablePreview(option)) .map((option) => ({ ...option, children: getEnabledAgentWorkflowOptionTree(option.children || []), @@ -1532,16 +1565,54 @@ export function normalizeAgentWorkflowUiConfig(value: unknown): AgentWorkflowUiC : depth < AGENT_WORKFLOW_MAX_OPTION_DEPTH ? defaultChildren : []; + const children = + depth < AGENT_WORKFLOW_MAX_OPTION_DEPTH + ? childSource + .map((child, childIndex) => + normalizeOption( + child, + childIndex, + optionKey, + usedOptionKeys, + defaultOption?.children || [], + depth + 1 + ) + ) + .sort((left, right) => left.sortOrder - right.sortOrder) + : []; + const directPreviewImageUrl = + normalizeText(optionRecord.previewImageUrl, 1000) || + defaultOption?.previewImageUrl || + ""; + const directPreviewImageSourceUrl = + normalizeText(optionRecord.previewImageSourceUrl, 1000) || + defaultOption?.previewImageSourceUrl || + ""; + const descendantPreview = getFirstAgentWorkflowOptionPreview({ + key: optionKey, + buttonName, + description: "", + previewImageUrl: directPreviewImageUrl, + previewImageSourceUrl: directPreviewImageSourceUrl, + enabled: true, + sortOrder: optionIndex, + promptFragment, + blockedOptionKeys: [], + specialModuleEnabled: false, + specialModuleExclusionEnabled: false, + specialModuleAllowedOptionKeys: [], + children, + }); return { key: optionKey, buttonName, description: normalizeText(optionRecord.description, 300) || defaultOption?.description || "", - previewImageUrl: normalizeText(optionRecord.previewImageUrl, 1000), + previewImageUrl: directPreviewImageUrl || descendantPreview?.previewImageUrl || "", previewImageSourceUrl: - normalizeText(optionRecord.previewImageSourceUrl, 1000) || - defaultOption?.previewImageSourceUrl || + directPreviewImageSourceUrl || + descendantPreview?.previewImageSourceUrl || "", enabled: normalizeBoolean(optionRecord.enabled, defaultOption?.enabled ?? true), sortOrder: normalizeNumber( @@ -1572,21 +1643,7 @@ export function normalizeAgentWorkflowUiConfig(value: unknown): AgentWorkflowUiC defaultOption?.specialModuleAllowedOptionKeys, AGENT_WORKFLOW_SPECIAL_MODULE_ALLOWED_KEYS_MAX ), - children: - depth < AGENT_WORKFLOW_MAX_OPTION_DEPTH - ? childSource - .map((child, childIndex) => - normalizeOption( - child, - childIndex, - optionKey, - usedOptionKeys, - defaultOption?.children || [], - depth + 1 - ) - ) - .sort((left, right) => left.sortOrder - right.sortOrder) - : [], + children, }; };