From 63bc04493766a1bc0dee8a7d96d1661a54c749a1 Mon Sep 17 00:00:00 2001 From: Martin Zink Date: Wed, 8 Jul 2026 21:16:16 +0200 Subject: [PATCH 1/7] MINIFICPP-2862 Add StandardValidator::NUMBER_VALIDATOR --- .../common/include/utils/ParsingUtils.h | 21 ++++- .../common/src/utils/ParsingUtils.cpp | 8 -- .../include/api/utils/ProcessorConfigUtils.h | 2 +- .../src/utils/minifi-c-utils.cpp | 3 + .../include/utils/ProcessorConfigUtils.h | 14 +++- libminifi/src/minifi-api.cpp | 1 + .../test/unit/PropertyValidationTests.cpp | 12 +++ .../minifi-cpp/core/PropertyValidator.h | 80 +++++++++++-------- minifi-api/include/minifi-api.h | 1 + 9 files changed, 96 insertions(+), 46 deletions(-) diff --git a/core-framework/common/include/utils/ParsingUtils.h b/core-framework/common/include/utils/ParsingUtils.h index 33236eda8a..85e18bde7b 100644 --- a/core-framework/common/include/utils/ParsingUtils.h +++ b/core-framework/common/include/utils/ParsingUtils.h @@ -40,7 +40,8 @@ std::expected parseDataSize(std::string_view input); std::expected parseUnixOctalPermissions(std::string_view input); -std::expected parseFloat(std::string_view input); +template +std::expected parseFloatingPoint(std::string_view input); template std::expected parseIntegralMinMax(const std::string_view input, const T minimum, const T maximum) { @@ -90,4 +91,22 @@ std::expected parseEnum(const std::string_view input) { return *result; } +template +std::expected parseFloatingPoint(const std::string_view input) { + const auto trimmed_input = utils::string::trim(input); + T value{}; + + const auto [ptr, ec] = std::from_chars(trimmed_input.data(), trimmed_input.data() + trimmed_input.size(), value); + + if (ec != std::errc()) { + return std::unexpected{core::ParsingErrorCode::GeneralParsingError}; + } + + if (ptr != trimmed_input.data() + trimmed_input.size()) { + return std::unexpected{core::ParsingErrorCode::GeneralParsingError}; + } + + return value; +} + } // namespace org::apache::nifi::minifi::parsing diff --git a/core-framework/common/src/utils/ParsingUtils.cpp b/core-framework/common/src/utils/ParsingUtils.cpp index 922704b950..75f095ef20 100644 --- a/core-framework/common/src/utils/ParsingUtils.cpp +++ b/core-framework/common/src/utils/ParsingUtils.cpp @@ -126,12 +126,4 @@ std::expected parseUnixOctalPermissions(const std::st return result; } -std::expected parseFloat(std::string_view input) { - try { - return std::stof(std::string{input}); - } catch(const std::exception&) { - return std::unexpected{core::ParsingErrorCode::GeneralParsingError}; - } -} - } // namespace org::apache::nifi::minifi::parsing diff --git a/extension-framework/cpp-extension-lib/include/api/utils/ProcessorConfigUtils.h b/extension-framework/cpp-extension-lib/include/api/utils/ProcessorConfigUtils.h index 2ec9571edd..ea2c17d9ed 100644 --- a/extension-framework/cpp-extension-lib/include/api/utils/ProcessorConfigUtils.h +++ b/extension-framework/cpp-extension-lib/include/api/utils/ProcessorConfigUtils.h @@ -134,7 +134,7 @@ inline std::optional parseOptionalFloatProperty(const core::ProcessContex if (property_str->empty()) { return std::nullopt; } - return parsing::parseFloat(*property_str) + return parsing::parseFloatingPoint(*property_str) | minifi::utils::orThrow(fmt::format("Expected parsable float from \"{}\"", property.name)); } return std::nullopt; diff --git a/extension-framework/cpp-extension-lib/src/utils/minifi-c-utils.cpp b/extension-framework/cpp-extension-lib/src/utils/minifi-c-utils.cpp index e11fd8972d..cf70d2c718 100644 --- a/extension-framework/cpp-extension-lib/src/utils/minifi-c-utils.cpp +++ b/extension-framework/cpp-extension-lib/src/utils/minifi-c-utils.cpp @@ -55,6 +55,9 @@ minifi_validator toStandardPropertyValidator(const minifi::core::PropertyValidat if (validator->getEquivalentNifiStandardValidatorName() == minifi::core::StandardPropertyValidators::PORT_VALIDATOR.getEquivalentNifiStandardValidatorName()) { return MINIFI_VALIDATOR_PORT; } + if (validator->getEquivalentNifiStandardValidatorName() == minifi::core::StandardPropertyValidators::NUMBER_VALIDATOR.getEquivalentNifiStandardValidatorName()) { + return MINIFI_VALIDATOR_NUMBER; + } gsl_FailFast(); } diff --git a/extension-framework/include/utils/ProcessorConfigUtils.h b/extension-framework/include/utils/ProcessorConfigUtils.h index b69ed40d97..852b9bf894 100644 --- a/extension-framework/include/utils/ProcessorConfigUtils.h +++ b/extension-framework/include/utils/ProcessorConfigUtils.h @@ -55,6 +55,18 @@ inline int64_t parseI64Property(const core::ProcessContext& ctx, const core::Pro | orThrow(fmt::format("Expected parsable int64_t from \"{}\"", property.name)); } +inline double parsef64Property(const core::ProcessContext& ctx, const core::PropertyReference& property, const core::FlowFile* flow_file = nullptr) { + return ctx.getProperty(property.name, flow_file) + | andThen(parsing::parseFloatingPoint) + | orThrow(fmt::format("Expected parsable double from \"{}\"", property.name)); +} + +inline double parsef32Property(const core::ProcessContext& ctx, const core::PropertyReference& property, const core::FlowFile* flow_file = nullptr) { + return ctx.getProperty(property.name, flow_file) + | andThen(parsing::parseFloatingPoint) + | orThrow(fmt::format("Expected parsable float from \"{}\"", property.name)); +} + inline std::chrono::milliseconds parseDurationProperty(const core::ProcessContext& ctx, const core::PropertyReference& property, const core::FlowFile* flow_file = nullptr) { return ctx.getProperty(property.name, flow_file) | andThen(parsing::parseDuration) @@ -133,7 +145,7 @@ inline std::optional parseOptionalFloatProperty(const core::ProcessContex if (property_str->empty()) { return std::nullopt; } - return parsing::parseFloat(*property_str) + return parsing::parseFloatingPoint(*property_str) | utils::orThrow(fmt::format("Expected parsable float from \"{}\"", property.name)); } return std::nullopt; diff --git a/libminifi/src/minifi-api.cpp b/libminifi/src/minifi-api.cpp index 1b484341c2..b1cc566443 100644 --- a/libminifi/src/minifi-api.cpp +++ b/libminifi/src/minifi-api.cpp @@ -88,6 +88,7 @@ gsl::not_null toPropertyValidator(minifi case MINIFI_VALIDATOR_UNSIGNED_INTEGER: return gsl::make_not_null(&minifi::core::StandardPropertyValidators::UNSIGNED_INTEGER_VALIDATOR); case MINIFI_VALIDATOR_DATA_SIZE: return gsl::make_not_null(&minifi::core::StandardPropertyValidators::DATA_SIZE_VALIDATOR); case MINIFI_VALIDATOR_PORT: return gsl::make_not_null(&minifi::core::StandardPropertyValidators::PORT_VALIDATOR); + case MINIFI_VALIDATOR_NUMBER: return gsl::make_not_null(&minifi::core::StandardPropertyValidators::NUMBER_VALIDATOR); } gsl_FailFast(); } diff --git a/libminifi/test/unit/PropertyValidationTests.cpp b/libminifi/test/unit/PropertyValidationTests.cpp index 62770fa9b9..0749551912 100644 --- a/libminifi/test/unit/PropertyValidationTests.cpp +++ b/libminifi/test/unit/PropertyValidationTests.cpp @@ -224,4 +224,16 @@ TEST_CASE("TimePeriodValue Property") { CHECK(component.setProperty(property.getName(), "20").error() == core::PropertyErrorCode::ValidationFailed); } +TEST_CASE("Number validator") { + static constexpr auto property_definition = PropertyDefinitionBuilder<>::createProperty("prop").withValidator(core::StandardPropertyValidators::NUMBER_VALIDATOR).build(); + const Property property{property_definition}; + TestConfigurableComponent component; + component.setSupportedProperties(std::array{property_definition}); + CHECK(component.setProperty(property.getName(), "20")); + CHECK(component.setProperty(property.getName(), "3.14")); + CHECK(component.setProperty(property.getName(), "0.0000000001")); + CHECK_FALSE(component.setProperty(property.getName(), "10 000")); + CHECK_FALSE(component.setProperty(property.getName(), "20 apples")); +} + } // namespace org::apache::nifi::minifi::core diff --git a/minifi-api/common/include/minifi-cpp/core/PropertyValidator.h b/minifi-api/common/include/minifi-cpp/core/PropertyValidator.h index 2d91905ffa..f864838a48 100644 --- a/minifi-api/common/include/minifi-cpp/core/PropertyValidator.h +++ b/minifi-api/common/include/minifi-cpp/core/PropertyValidator.h @@ -25,27 +25,31 @@ namespace org::apache::nifi::minifi::core { class PropertyValidator { public: virtual constexpr ~PropertyValidator() {} // NOLINT can't use = default because of gcc bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93413 + PropertyValidator() = default; + PropertyValidator(const PropertyValidator&) = delete; + PropertyValidator(PropertyValidator&&) = delete; + PropertyValidator& operator=(const PropertyValidator& other) = delete; + PropertyValidator& operator=(PropertyValidator&& other) = delete; [[nodiscard]] virtual std::optional getEquivalentNifiStandardValidatorName() const = 0; [[nodiscard]] virtual bool validate(std::string_view input) const = 0; }; - class AlwaysValidValidator final : public PropertyValidator { public: - AlwaysValidValidator() = default; - constexpr ~AlwaysValidValidator() override {} // NOLINT see comment at parent - - [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { return "VALID"; } - [[nodiscard]] bool validate(std::string_view) const override { return true; } + [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { + return "VALID"; + } + [[nodiscard]] bool validate(std::string_view) const override { + return true; + } }; class NonBlankValidator final : public PropertyValidator { public: - NonBlankValidator() = default; - constexpr ~NonBlankValidator() override {} // NOLINT see comment at parent - - [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { return "NON_BLANK_VALIDATOR"; } + [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { + return "NON_BLANK_VALIDATOR"; + } [[nodiscard]] bool validate(const std::string_view input) const override { return !utils::string::trim(input).empty(); } @@ -53,10 +57,9 @@ class NonBlankValidator final : public PropertyValidator { class TimePeriodValidator final : public PropertyValidator { public: - TimePeriodValidator() = default; - constexpr ~TimePeriodValidator() override {} // NOLINT see comment at parent - - [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { return "TIME_PERIOD_VALIDATOR"; } + [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { + return "TIME_PERIOD_VALIDATOR"; + } [[nodiscard]] bool validate(const std::string_view input) const override { const auto parsed_time = parsing::parseDuration(input); return parsed_time.has_value(); @@ -65,10 +68,9 @@ class TimePeriodValidator final : public PropertyValidator { class BooleanValidator final : public PropertyValidator { public: - BooleanValidator() = default; - constexpr ~BooleanValidator() override {} // NOLINT see comment at parent - - [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { return "BOOLEAN_VALIDATOR"; } + [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { + return "BOOLEAN_VALIDATOR"; + } [[nodiscard]] bool validate(const std::string_view input) const override { const auto parsed_bool = parsing::parseBool(input); return parsed_bool.has_value(); @@ -77,10 +79,9 @@ class BooleanValidator final : public PropertyValidator { class IntegerValidator final : public PropertyValidator { public: - IntegerValidator() = default; - constexpr ~IntegerValidator() override {} // NOLINT see comment at parent - - [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { return "INTEGER_VALIDATOR"; } + [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { + return "INTEGER_VALIDATOR"; + } [[nodiscard]] bool validate(const std::string_view input) const override { const auto parsed_integer = parsing::parseIntegral(input); return parsed_integer.has_value(); @@ -89,10 +90,9 @@ class IntegerValidator final : public PropertyValidator { class UnsignedIntegerValidator final : public PropertyValidator { public: - UnsignedIntegerValidator() = default; - constexpr ~UnsignedIntegerValidator() override {} // NOLINT see comment at parent - - [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { return "NON_NEGATIVE_INTEGER_VALIDATOR"; } + [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { + return "NON_NEGATIVE_INTEGER_VALIDATOR"; + } [[nodiscard]] bool validate(const std::string_view input) const override { const auto parsed_integer = parsing::parseIntegral(input); return parsed_integer.has_value(); @@ -101,10 +101,9 @@ class UnsignedIntegerValidator final : public PropertyValidator { class DataSizeValidator final : public PropertyValidator { public: - DataSizeValidator() = default; - constexpr ~DataSizeValidator() override {} // NOLINT see comment at parent - - [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { return "DATA_SIZE_VALIDATOR"; } + [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { + return "DATA_SIZE_VALIDATOR"; + } [[nodiscard]] bool validate(const std::string_view input) const override { const auto parsed_data_size = parsing::parseDataSize(input); return parsed_data_size.has_value(); @@ -113,16 +112,26 @@ class DataSizeValidator final : public PropertyValidator { class PortValidator final : public core::PropertyValidator { public: - PortValidator() = default; - constexpr ~PortValidator() override {} // NOLINT see comment at parent - - [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { return "PORT_VALIDATOR"; } + [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { + return "PORT_VALIDATOR"; + } [[nodiscard]] bool validate(const std::string_view input) const override { const auto parsed_integer = parsing::parseIntegralMinMax(input, 0, 65535); return parsed_integer.has_value(); } }; +class NumberValidator final : public core::PropertyValidator { + public: + [[nodiscard]] std::optional getEquivalentNifiStandardValidatorName() const override { + return "NUMBER_VALIDATOR"; + } + [[nodiscard]] bool validate(const std::string_view input) const override { + const auto parsed_integer = parsing::parseFloatingPoint(input); + return parsed_integer.has_value(); + } +}; + namespace StandardPropertyValidators { inline constexpr auto ALWAYS_VALID_VALIDATOR = AlwaysValidValidator{}; inline constexpr auto NON_BLANK_VALIDATOR = NonBlankValidator{}; @@ -132,6 +141,7 @@ inline constexpr auto INTEGER_VALIDATOR = IntegerValidator{}; inline constexpr auto UNSIGNED_INTEGER_VALIDATOR = UnsignedIntegerValidator{}; inline constexpr auto DATA_SIZE_VALIDATOR = DataSizeValidator{}; inline constexpr auto PORT_VALIDATOR = PortValidator{}; -} +inline constexpr auto NUMBER_VALIDATOR = NumberValidator{}; +} // namespace StandardPropertyValidators } // namespace org::apache::nifi::minifi::core diff --git a/minifi-api/include/minifi-api.h b/minifi-api/include/minifi-api.h index 2ee6f87aba..6f4cf5bcd7 100644 --- a/minifi-api/include/minifi-api.h +++ b/minifi-api/include/minifi-api.h @@ -119,6 +119,7 @@ enum minifi_validator : uint32_t { MINIFI_VALIDATOR_UNSIGNED_INTEGER = 5, MINIFI_VALIDATOR_DATA_SIZE = 6, MINIFI_VALIDATOR_PORT = 7, + MINIFI_VALIDATOR_NUMBER = 8, }; struct minifi_property_definition { From 778b8cd66ad5d5672272ddc3aa6be3bcf48e7573 Mon Sep 17 00:00:00 2001 From: Martin Zink Date: Thu, 9 Jul 2026 09:51:21 +0200 Subject: [PATCH 2/7] review changes --- extension-framework/include/utils/ProcessorConfigUtils.h | 4 ++-- minifi-api/common/include/minifi-cpp/core/PropertyValidator.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extension-framework/include/utils/ProcessorConfigUtils.h b/extension-framework/include/utils/ProcessorConfigUtils.h index 852b9bf894..b3b5071e55 100644 --- a/extension-framework/include/utils/ProcessorConfigUtils.h +++ b/extension-framework/include/utils/ProcessorConfigUtils.h @@ -55,13 +55,13 @@ inline int64_t parseI64Property(const core::ProcessContext& ctx, const core::Pro | orThrow(fmt::format("Expected parsable int64_t from \"{}\"", property.name)); } -inline double parsef64Property(const core::ProcessContext& ctx, const core::PropertyReference& property, const core::FlowFile* flow_file = nullptr) { +inline double parseF64Property(const core::ProcessContext& ctx, const core::PropertyReference& property, const core::FlowFile* flow_file = nullptr) { return ctx.getProperty(property.name, flow_file) | andThen(parsing::parseFloatingPoint) | orThrow(fmt::format("Expected parsable double from \"{}\"", property.name)); } -inline double parsef32Property(const core::ProcessContext& ctx, const core::PropertyReference& property, const core::FlowFile* flow_file = nullptr) { +inline float parseF32Property(const core::ProcessContext& ctx, const core::PropertyReference& property, const core::FlowFile* flow_file = nullptr) { return ctx.getProperty(property.name, flow_file) | andThen(parsing::parseFloatingPoint) | orThrow(fmt::format("Expected parsable float from \"{}\"", property.name)); diff --git a/minifi-api/common/include/minifi-cpp/core/PropertyValidator.h b/minifi-api/common/include/minifi-cpp/core/PropertyValidator.h index f864838a48..06f66e9c28 100644 --- a/minifi-api/common/include/minifi-cpp/core/PropertyValidator.h +++ b/minifi-api/common/include/minifi-cpp/core/PropertyValidator.h @@ -127,8 +127,8 @@ class NumberValidator final : public core::PropertyValidator { return "NUMBER_VALIDATOR"; } [[nodiscard]] bool validate(const std::string_view input) const override { - const auto parsed_integer = parsing::parseFloatingPoint(input); - return parsed_integer.has_value(); + const auto parsed_number = parsing::parseFloatingPoint(input); + return parsed_number.has_value(); } }; From 1e3288473ee7a1c2f0428e3e4f3f4a5398974071 Mon Sep 17 00:00:00 2001 From: Martin Zink Date: Thu, 9 Jul 2026 10:12:42 +0200 Subject: [PATCH 3/7] add NUMBER_VALIDATOR to RunLlamaCppInference::Temperature,TopP,MinP --- extensions/llamacpp/processors/RunLlamaCppInference.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/extensions/llamacpp/processors/RunLlamaCppInference.h b/extensions/llamacpp/processors/RunLlamaCppInference.h index 16cf7a9c68..877e2a3056 100644 --- a/extensions/llamacpp/processors/RunLlamaCppInference.h +++ b/extensions/llamacpp/processors/RunLlamaCppInference.h @@ -71,6 +71,7 @@ class RunLlamaCppInference : public api::core::ProcessorImpl { .build(); EXTENSIONAPI static constexpr auto Temperature = core::PropertyDefinitionBuilder<>::createProperty("Temperature") .withDescription("The temperature to use for sampling.") + .withValidator(core::StandardPropertyValidators::NUMBER_VALIDATOR) .withDefaultValue("0.8") .build(); EXTENSIONAPI static constexpr auto TopK = core::PropertyDefinitionBuilder<>::createProperty("Top K") @@ -79,10 +80,12 @@ class RunLlamaCppInference : public api::core::ProcessorImpl { .build(); EXTENSIONAPI static constexpr auto TopP = core::PropertyDefinitionBuilder<>::createProperty("Top P") .withDescription("Limit the next token selection to a subset of tokens with a cumulative probability above a threshold P. 1.0 = disabled.") + .withValidator(core::StandardPropertyValidators::NUMBER_VALIDATOR) .withDefaultValue("0.9") .build(); EXTENSIONAPI static constexpr auto MinP = core::PropertyDefinitionBuilder<>::createProperty("Min P") .withDescription("Sets a minimum base probability threshold for token selection. 0.0 = disabled.") + .withValidator(core::StandardPropertyValidators::NUMBER_VALIDATOR) .build(); EXTENSIONAPI static constexpr auto MinKeep = core::PropertyDefinitionBuilder<>::createProperty("Min Keep") .withDescription("If greater than 0, force samplers to return N possible tokens at minimum.") From 754c075888f801708de1a87f1f873b0e449c07b5 Mon Sep 17 00:00:00 2001 From: Martin Zink Date: Thu, 9 Jul 2026 11:34:55 +0200 Subject: [PATCH 4/7] add NUMBER_VALIDATOR to python --- extensions/python/pythonprocessors/nifiapi/properties.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/extensions/python/pythonprocessors/nifiapi/properties.py b/extensions/python/pythonprocessors/nifiapi/properties.py index 3cbd4c58c3..fe0dab092f 100644 --- a/extensions/python/pythonprocessors/nifiapi/properties.py +++ b/extensions/python/pythonprocessors/nifiapi/properties.py @@ -53,6 +53,9 @@ def createRegexValidator(self, *args) -> int: def createLongValidator(self, *args) -> int: return StandardValidators.LONG_VALIDATOR + def createNumberValidator(self, *args) -> int: + return StandardValidators.NUMBER_VALIDATOR + class StandardValidators: _standard_validators = ValidatorGenerator() @@ -87,6 +90,7 @@ class MinifiPropertyTypes: TIME_PERIOD_TYPE = 4 NON_BLANK_TYPE = 5 PORT_TYPE = 6 + NUMBER_TYPE = 7 def translateStandardValidatorToMiNiFiPropertype(validators: List[int]) -> int: @@ -108,6 +112,8 @@ def translateStandardValidatorToMiNiFiPropertype(validators: List[int]) -> int: return MinifiPropertyTypes.NON_BLANK_TYPE if validator == StandardValidators.PORT_VALIDATOR: return MinifiPropertyTypes.PORT_TYPE + if validator == StandardValidators.NUMBER_VALIDATOR: + return MinifiPropertyTypes.NUMBER_TYPE return None From 8338baf2e305316f3606e4a05c9296dbc4851e4f Mon Sep 17 00:00:00 2001 From: Martin Zink Date: Thu, 9 Jul 2026 14:11:52 +0200 Subject: [PATCH 5/7] since RunLlamaCppInference::Temperature and TopP have default values, but we would like to use them optionally we cant add this validator because it breaks the setting the value to "" to disable workflow --- extensions/llamacpp/processors/RunLlamaCppInference.h | 2 -- extensions/llamacpp/tests/RunLlamaCppInferenceTests.cpp | 4 ---- 2 files changed, 6 deletions(-) diff --git a/extensions/llamacpp/processors/RunLlamaCppInference.h b/extensions/llamacpp/processors/RunLlamaCppInference.h index 877e2a3056..67cd14a9ee 100644 --- a/extensions/llamacpp/processors/RunLlamaCppInference.h +++ b/extensions/llamacpp/processors/RunLlamaCppInference.h @@ -71,7 +71,6 @@ class RunLlamaCppInference : public api::core::ProcessorImpl { .build(); EXTENSIONAPI static constexpr auto Temperature = core::PropertyDefinitionBuilder<>::createProperty("Temperature") .withDescription("The temperature to use for sampling.") - .withValidator(core::StandardPropertyValidators::NUMBER_VALIDATOR) .withDefaultValue("0.8") .build(); EXTENSIONAPI static constexpr auto TopK = core::PropertyDefinitionBuilder<>::createProperty("Top K") @@ -80,7 +79,6 @@ class RunLlamaCppInference : public api::core::ProcessorImpl { .build(); EXTENSIONAPI static constexpr auto TopP = core::PropertyDefinitionBuilder<>::createProperty("Top P") .withDescription("Limit the next token selection to a subset of tokens with a cumulative probability above a threshold P. 1.0 = disabled.") - .withValidator(core::StandardPropertyValidators::NUMBER_VALIDATOR) .withDefaultValue("0.9") .build(); EXTENSIONAPI static constexpr auto MinP = core::PropertyDefinitionBuilder<>::createProperty("Min P") diff --git a/extensions/llamacpp/tests/RunLlamaCppInferenceTests.cpp b/extensions/llamacpp/tests/RunLlamaCppInferenceTests.cpp index 3582c21909..fb22075214 100644 --- a/extensions/llamacpp/tests/RunLlamaCppInferenceTests.cpp +++ b/extensions/llamacpp/tests/RunLlamaCppInferenceTests.cpp @@ -233,10 +233,6 @@ TEST_CASE("Invalid values for optional double type properties throw exception") REQUIRE(controller.getProcessor()->setProperty(processors::RunLlamaCppInference::TopP.name, "invalid_value")); property_name = processors::RunLlamaCppInference::TopP.name; } - SECTION("Invalid value for Min P property") { - REQUIRE(controller.getProcessor()->setProperty(processors::RunLlamaCppInference::MinP.name, "invalid_value")); - property_name = processors::RunLlamaCppInference::MinP.name; - } REQUIRE_THROWS(controller.trigger(minifi::test::InputFlowFileData{.content = "42", .attributes = {}})); CHECK(minifi::test::utils::verifyLogLinePresenceInPollTime(1s, From 9a4750f4d0aab58318b4eba2e63944efb61c80ac Mon Sep 17 00:00:00 2001 From: Martin Zink Date: Thu, 9 Jul 2026 16:54:16 +0200 Subject: [PATCH 6/7] add PropertyValidatorCode::NUMBER --- extensions/python/ExecutePythonProcessor.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/extensions/python/ExecutePythonProcessor.cpp b/extensions/python/ExecutePythonProcessor.cpp index 184acad784..7ef4ae73a4 100644 --- a/extensions/python/ExecutePythonProcessor.cpp +++ b/extensions/python/ExecutePythonProcessor.cpp @@ -138,7 +138,8 @@ enum class PropertyValidatorCode : int64_t { DATA_SIZE = 3, TIME_PERIOD = 4, NON_BLANK = 5, - PORT = 6 + PORT = 6, + NUMBER = 7 }; const core::PropertyValidator& translateCodeToPropertyValidator(const PropertyValidatorCode& code) { @@ -156,6 +157,8 @@ const core::PropertyValidator& translateCodeToPropertyValidator(const PropertyVa return core::StandardPropertyValidators::NON_BLANK_VALIDATOR; case PropertyValidatorCode::PORT: return core::StandardPropertyValidators::PORT_VALIDATOR; + case PropertyValidatorCode::NUMBER: + return core::StandardPropertyValidators::NUMBER_VALIDATOR; default: throw std::invalid_argument("Unknown PropertyValidatorCode"); } From ce94bc4f6fe4b3bde703903ee83342fd1876610f Mon Sep 17 00:00:00 2001 From: Martin Zink Date: Tue, 14 Jul 2026 10:14:28 +0200 Subject: [PATCH 7/7] update ubuntu_22_04_clang_arm_manifest.json --- .github/references/ubuntu_22_04_clang_arm_manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/references/ubuntu_22_04_clang_arm_manifest.json b/.github/references/ubuntu_22_04_clang_arm_manifest.json index bcb495d3e9..750f3954b7 100644 --- a/.github/references/ubuntu_22_04_clang_arm_manifest.json +++ b/.github/references/ubuntu_22_04_clang_arm_manifest.json @@ -10268,7 +10268,7 @@ "Min P": { "name": "Min P", "description": "Sets a minimum base probability threshold for token selection. 0.0 = disabled.", - "validator": "VALID", + "validator": "NUMBER_VALIDATOR", "required": "false", "sensitive": "false", "expressionLanguageScope": "NONE"