fix: use default values for optional workflow input variables (#28546) (#28527)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Chen Jiaju 2025-11-24 10:08:26 +08:00 committed by GitHub
parent e0824c2d93
commit 3841e8578f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 221 additions and 1 deletions

View File

@ -112,6 +112,7 @@ class VariableEntity(BaseModel):
type: VariableEntityType
required: bool = False
hide: bool = False
default: Any = None
max_length: int | None = None
options: Sequence[str] = Field(default_factory=list)
allowed_file_types: Sequence[FileType] | None = Field(default_factory=list)

View File

@ -93,7 +93,11 @@ class BaseAppGenerator:
if value is None:
if variable_entity.required:
raise ValueError(f"{variable_entity.variable} is required in input form")
return value
# Use default value and continue validation to ensure type conversion
value = variable_entity.default
# If default is also None, return None directly
if value is None:
return None
if variable_entity.type in {
VariableEntityType.TEXT_INPUT,

View File

@ -50,3 +50,218 @@ def test_validate_input_with_none_for_required_variable():
)
assert str(exc_info.value) == "test_var is required in input form"
def test_validate_inputs_with_default_value():
"""Test that default values are used when input is None for optional variables"""
base_app_generator = BaseAppGenerator()
# Test with string default value for TEXT_INPUT
var_string = VariableEntity(
variable="test_var",
label="test_var",
type=VariableEntityType.TEXT_INPUT,
required=False,
default="default_string",
)
result = base_app_generator._validate_inputs(
variable_entity=var_string,
value=None,
)
assert result == "default_string"
# Test with string default value for PARAGRAPH
var_paragraph = VariableEntity(
variable="test_paragraph",
label="test_paragraph",
type=VariableEntityType.PARAGRAPH,
required=False,
default="default paragraph text",
)
result = base_app_generator._validate_inputs(
variable_entity=var_paragraph,
value=None,
)
assert result == "default paragraph text"
# Test with SELECT default value
var_select = VariableEntity(
variable="test_select",
label="test_select",
type=VariableEntityType.SELECT,
required=False,
default="option1",
options=["option1", "option2", "option3"],
)
result = base_app_generator._validate_inputs(
variable_entity=var_select,
value=None,
)
assert result == "option1"
# Test with number default value (int)
var_number_int = VariableEntity(
variable="test_number_int",
label="test_number_int",
type=VariableEntityType.NUMBER,
required=False,
default=42,
)
result = base_app_generator._validate_inputs(
variable_entity=var_number_int,
value=None,
)
assert result == 42
# Test with number default value (float)
var_number_float = VariableEntity(
variable="test_number_float",
label="test_number_float",
type=VariableEntityType.NUMBER,
required=False,
default=3.14,
)
result = base_app_generator._validate_inputs(
variable_entity=var_number_float,
value=None,
)
assert result == 3.14
# Test with number default value as string (frontend sends as string)
var_number_string = VariableEntity(
variable="test_number_string",
label="test_number_string",
type=VariableEntityType.NUMBER,
required=False,
default="123",
)
result = base_app_generator._validate_inputs(
variable_entity=var_number_string,
value=None,
)
assert result == 123
assert isinstance(result, int)
# Test with float number default value as string
var_number_float_string = VariableEntity(
variable="test_number_float_string",
label="test_number_float_string",
type=VariableEntityType.NUMBER,
required=False,
default="45.67",
)
result = base_app_generator._validate_inputs(
variable_entity=var_number_float_string,
value=None,
)
assert result == 45.67
assert isinstance(result, float)
# Test with CHECKBOX default value (bool)
var_checkbox_true = VariableEntity(
variable="test_checkbox_true",
label="test_checkbox_true",
type=VariableEntityType.CHECKBOX,
required=False,
default=True,
)
result = base_app_generator._validate_inputs(
variable_entity=var_checkbox_true,
value=None,
)
assert result is True
var_checkbox_false = VariableEntity(
variable="test_checkbox_false",
label="test_checkbox_false",
type=VariableEntityType.CHECKBOX,
required=False,
default=False,
)
result = base_app_generator._validate_inputs(
variable_entity=var_checkbox_false,
value=None,
)
assert result is False
# Test with None as explicit default value
var_none_default = VariableEntity(
variable="test_none",
label="test_none",
type=VariableEntityType.TEXT_INPUT,
required=False,
default=None,
)
result = base_app_generator._validate_inputs(
variable_entity=var_none_default,
value=None,
)
assert result is None
# Test that actual input value takes precedence over default
result = base_app_generator._validate_inputs(
variable_entity=var_string,
value="actual_value",
)
assert result == "actual_value"
# Test that actual number input takes precedence over default
result = base_app_generator._validate_inputs(
variable_entity=var_number_int,
value=999,
)
assert result == 999
# Test with FILE default value (dict format from frontend)
var_file = VariableEntity(
variable="test_file",
label="test_file",
type=VariableEntityType.FILE,
required=False,
default={"id": "file123", "name": "default.pdf"},
)
result = base_app_generator._validate_inputs(
variable_entity=var_file,
value=None,
)
assert result == {"id": "file123", "name": "default.pdf"}
# Test with FILE_LIST default value (list of dicts)
var_file_list = VariableEntity(
variable="test_file_list",
label="test_file_list",
type=VariableEntityType.FILE_LIST,
required=False,
default=[{"id": "file1", "name": "doc1.pdf"}, {"id": "file2", "name": "doc2.pdf"}],
)
result = base_app_generator._validate_inputs(
variable_entity=var_file_list,
value=None,
)
assert result == [{"id": "file1", "name": "doc1.pdf"}, {"id": "file2", "name": "doc2.pdf"}]