This is an automated email from the ASF dual-hosted git repository. luigidemasi pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit a97d481a20a9b7f5b4cd1f6053ef4ef49b362690 Author: Luigi De Masi <[email protected]> AuthorDate: Thu Oct 15 08:52:41 2026 +0200 CAMEL-25669: Identify refused questions in Decisions batches Include the zero-based question index and optional request name in refusal exceptions so callers can identify the failed question. Cover named and unnamed questions after a successful answer in a batch. Co-authored-by: OpenAI Codex <[email protected]> Signed-off-by: Luigi De Masi <[email protected]> --- .../component/openai/OpenAIDecisionsSupport.java | 4 +++- .../component/openai/OpenAIDecisionsTest.java | 24 +++++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIDecisionsSupport.java b/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIDecisionsSupport.java index 751e54bc0f59..d50e9955d12d 100644 --- a/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIDecisionsSupport.java +++ b/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIDecisionsSupport.java @@ -198,7 +198,9 @@ public final class OpenAIDecisionsSupport { var answer = response.answers().get(i); Optional<String> answerName; if (answer.isRefusal()) { - throw new OpenAIDecisionRefusalException("OpenAI declined to answer a decision question"); + throw new OpenAIDecisionRefusalException( + "OpenAI declined to answer decision question at index " + i + + name(question).map(n -> " ('" + n + "')").orElse("")); } else if (question.isPredicate() && answer.isPredicate()) { probability(answer.asPredicate().probability()); answerName = answer.asPredicate().name(); diff --git a/components/camel-ai/camel-openai/src/test/java/org/apache/camel/component/openai/OpenAIDecisionsTest.java b/components/camel-ai/camel-openai/src/test/java/org/apache/camel/component/openai/OpenAIDecisionsTest.java index ee976ee25529..d9114948c030 100644 --- a/components/camel-ai/camel-openai/src/test/java/org/apache/camel/component/openai/OpenAIDecisionsTest.java +++ b/components/camel-ai/camel-openai/src/test/java/org/apache/camel/component/openai/OpenAIDecisionsTest.java @@ -19,6 +19,7 @@ package org.apache.camel.component.openai; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import com.openai.client.OpenAIClient; import com.openai.models.decisions.Decision; @@ -28,6 +29,8 @@ import com.openai.models.decisions.DecisionInputMessage; import com.openai.models.decisions.DecisionInputPart; import org.apache.camel.impl.DefaultCamelContext; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -74,7 +77,26 @@ class OpenAIDecisionsTest { when(client.decisions().create(request)).thenReturn(Decision.builder().model("gpt-6-luna") .addAnswer(Decision.Answer.Refusal.builder().name("test").build()).usage(usage()).build()); assertThatThrownBy(() -> OpenAIDecisionsSupport.execute(client, request)) - .isInstanceOf(OpenAIDecisionRefusalException.class); + .isInstanceOf(OpenAIDecisionRefusalException.class) + .hasMessage("OpenAI declined to answer decision question at index 0 ('test')"); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false }) + void identifiesRefusedQuestionInBatch(boolean named) { + var question = DecisionCreateParams.Question.Predicate.builder().instructions("Is it urgent?"); + if (named) { + question.name("urgent"); + } + DecisionCreateParams request = request().toBuilder().addQuestion(question.build()).build(); + OpenAIClient client = mock(OpenAIClient.class, RETURNS_DEEP_STUBS); + Decision response = Decision.builder().model("gpt-6-luna") + .addAnswer(Decision.Answer.Predicate.builder().name("test").probability(0.9).build()) + .addAnswer(Decision.Answer.Refusal.builder().name(Optional.empty()).build()).usage(usage()).build(); + when(client.decisions().create(request)).thenReturn(response); + assertThatThrownBy(() -> OpenAIDecisionsSupport.execute(client, request)) + .isInstanceOf(OpenAIDecisionRefusalException.class) + .hasMessage("OpenAI declined to answer decision question at index 1" + (named ? " ('urgent')" : "")); } @Test
