luigidemasi commented on code in PR #26813: URL: https://github.com/apache/camel/pull/26813#discussion_r4090769151
########## components/camel-ai/camel-semantic/src/main/java/org/apache/camel/semantic/SemanticResult.java: ########## @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.semantic; + +import java.util.Map; + +/** + * A provider answer. Value is Boolean, a category String, or a numeric score. A boolean provider may supply only + * probability; the question then defines the decision policy. Missing probabilities/confidence remain absent. Metadata + * may contain provider/model identity, revision and usage. It must not contain credentials or input state. + */ +public final class SemanticResult { + private final Object value; + private final Double probability; + private final Map<String, Double> probabilities; + private final Double confidence; + private final Map<String, Object> metadata; + + public SemanticResult(Object value, Double probability, Map<String, Double> probabilities, + Double confidence, Map<String, Object> metadata) { + this.value = value; + this.probability = probability; + this.probabilities = probabilities == null ? Map.of() : Map.copyOf(probabilities); + this.confidence = confidence; + this.metadata = metadata == null ? Map.of() : Map.copyOf(metadata); + checkProbability(probability); + checkProbability(confidence); + this.probabilities.values().forEach(SemanticResult::checkProbability); + } + + private static void checkProbability(Double value) { + if (value != null && (!Double.isFinite(value) || value < 0 || value > 1)) { + throw new IllegalArgumentException("Semantic probabilities and confidence must be within [0,1]"); + } + } + + public Object decision(SemanticQuestion question) { + switch (question.getType()) { + case BOOLEAN: + if (probability != null) { + double threshold = question.getThreshold(); + double uncertainty = question.getUncertainty(); + if (uncertainty > 0 && probability >= threshold - uncertainty && probability <= threshold + uncertainty) { + if (question.getUncertaintyPolicy() == SemanticQuestion.UncertaintyPolicy.FAIL) { + throw new IllegalStateException("Semantic boolean decision is uncertain"); + } + return false; + } + return probability >= threshold; + } + if (value instanceof Boolean && question.getUncertainty() == 0 && question.getThreshold() == 0.5) { Review Comment: Thanks for raising the distinction between a provider decision and a probability. We are retaining the current behavior: Camel owns and applies the configured threshold and uncertainty policy. For a question with `threshold: 0.7`, the adapter must return a probability so Camel can enforce that rule. A bare Boolean cannot establish whether the result meets that threshold or falls inside an uncertainty band; accepting it unconditionally would leave the configured policy unenforced by Camel. Boolean-only results remain supported with the default policy (`threshold: 0.5`, no uncertainty band). An adapter could apply a custom policy internally, but accepting that final Boolean would be a different contract that delegates policy enforcement to the adapter. This implementation keeps that responsibility in Camel. Added `booleanOnlyProviderCannotSilentlyIgnoreProbabilityPolicy` in [0c5ba894fe80](https://github.com/apache/camel/commit/0c5ba894fe801efd3c184fa6f574394fc2d003ce) to cover acceptance under the default policy and rejection with a custom threshold or uncertainty band. The documented behavior is unchanged. _AI-generated by Codex on behalf of [luigidemasi](https://github.com/luigidemasi)._ -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
