diff --git a/web/src/app/home/components/dynamic-form/DynamicFormItemComponent.tsx b/web/src/app/home/components/dynamic-form/DynamicFormItemComponent.tsx index 18f0e7452..4bd31b4b0 100644 --- a/web/src/app/home/components/dynamic-form/DynamicFormItemComponent.tsx +++ b/web/src/app/home/components/dynamic-form/DynamicFormItemComponent.tsx @@ -67,6 +67,18 @@ import SettingsDialog, { import ToolResourceSelectors from '@/app/home/components/dynamic-form/ToolResourceSelectors'; import { LANGBOT_MODELS_PROVIDER_REQUESTER } from '@/app/home/components/models-dialog/types'; +const EMPTY_SELECT_ITEM_VALUE = '__langbot_empty_select_item_value__'; + +function toSelectValue(value: unknown): string { + return typeof value === 'string' ? value : ''; +} + +function hasNonEmptyUuid( + item: T, +): item is T & { uuid: string } { + return typeof item.uuid === 'string' && item.uuid.length > 0; +} + export default function DynamicFormItemComponent({ config, field, @@ -380,19 +392,33 @@ export default function DynamicFormItemComponent({ ); - case DynamicFormItemType.SELECT: + case DynamicFormItemType.SELECT: { + const hasEmptyOption = + config.options?.some((option) => option.name === '') ?? false; + const selectValue = + hasEmptyOption && field.value === '' + ? EMPTY_SELECT_ITEM_VALUE + : toSelectValue(field.value); + return ( - + field.onChange(value === EMPTY_SELECT_ITEM_VALUE ? '' : value) + } + > - {config.options?.map((option) => ( + {config.options?.map((option, index) => ( {extractI18nObject(option.label)} @@ -401,6 +427,7 @@ export default function DynamicFormItemComponent({ ); + } case DynamicFormItemType.LLM_MODEL_SELECTOR: // Separate space models from regular models @@ -455,7 +482,7 @@ export default function DynamicFormItemComponent({ {Object.entries(groupedModels).map(([providerName, models]) => ( {providerName} - {models.map((model) => ( + {models.filter(hasNonEmptyUuid).map((model) => ( {model.name} @@ -559,7 +586,7 @@ export default function DynamicFormItemComponent({ {providerName} - {models.map((model) => ( + {models.filter(hasNonEmptyUuid).map((model) => ( {model.name} @@ -656,7 +683,7 @@ export default function DynamicFormItemComponent({ ([providerName, models]) => ( {providerName} - {models.map((model) => ( + {models.filter(hasNonEmptyUuid).map((model) => ( {model.name} @@ -748,7 +775,7 @@ export default function DynamicFormItemComponent({ {providerName} - {models.map((model) => ( + {models.filter(hasNonEmptyUuid).map((model) => ( {model.name} @@ -813,7 +840,7 @@ export default function DynamicFormItemComponent({ ([providerName, models]) => ( {providerName} - {models.map((model) => ( + {models.filter(hasNonEmptyUuid).map((model) => ( {model.name} @@ -908,7 +935,7 @@ export default function DynamicFormItemComponent({ ([providerName, models]) => ( {providerName} - {models.map((model) => ( + {models.filter(hasNonEmptyUuid).map((model) => ( {model.name} @@ -1013,7 +1040,7 @@ export default function DynamicFormItemComponent({ {providerName} - {models.map((model) => ( + {models.filter(hasNonEmptyUuid).map((model) => ( {model.name} @@ -1223,8 +1250,8 @@ export default function DynamicFormItemComponent({ {Object.entries(kbsByEngine).map(([engineName, kbs]) => ( {engineName} - {kbs.map((base) => ( - + {kbs.filter(hasNonEmptyUuid).map((base) => ( +
{base.emoji && ( {base.emoji} @@ -1417,8 +1444,8 @@ export default function DynamicFormItemComponent({ - {bots.map((bot) => ( - + {bots.filter(hasNonEmptyUuid).map((bot) => ( + {bot.name} ))}