This is an automated email from the ASF dual-hosted git repository.

fmariani pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 9796b7c0b71f Fix langchain4j agent test
9796b7c0b71f is described below

commit 9796b7c0b71f98b172102bdf3ffdefd4e248c6e2
Author: Croway <[email protected]>
AuthorDate: Wed Jan 21 17:26:28 2026 +0100

    Fix langchain4j agent test
---
 .../LangChain4jAgentGuardrailsIntegrationIT.java    |  5 ++++-
 .../integration/LangChain4jAgentMcpToolsIT.java     | 13 ++++++++-----
 .../LangChain4jAgentMultimodalityIT.java            | 12 ++++++++++++
 .../integration/LangChain4jAgentWrappedFileIT.java  | 18 +++++++++++++-----
 .../agent/pojos/TestJsonOutputGuardrail.java        | 21 +++++++++++++++++++++
 5 files changed, 58 insertions(+), 11 deletions(-)

diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentGuardrailsIntegrationIT.java
 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentGuardrailsIntegrationIT.java
index 98fc914c8e8c..75921509abea 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentGuardrailsIntegrationIT.java
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentGuardrailsIntegrationIT.java
@@ -142,10 +142,13 @@ public class LangChain4jAgentGuardrailsIntegrationIT 
extends CamelTestSupport {
 
     @Test
     void testAgentWithJsonOutputGuardrailFailure() throws InterruptedException 
{
+        // Disable reprompting so the guardrail fails immediately with fatal 
error
+        TestJsonOutputGuardrail.setAllowReprompt(false);
+
         MockEndpoint mockEndpoint = 
this.context.getEndpoint("mock:agent-response", MockEndpoint.class);
         mockEndpoint.expectedMessageCount(0); // No message should reach the 
endpoint due to guardrail failure
 
-        String nonJsonRequest = "Tell me a simple story about a cat in one 
sentence.";
+        String nonJsonRequest = "Tell me a simple story about a cat in one 
sentence";
 
         // Expect an exception due to guardrail failure
         Exception exception = assertThrows(Exception.class, () -> {
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentMcpToolsIT.java
 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentMcpToolsIT.java
index 6fff04f75f7a..eaec43962cfa 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentMcpToolsIT.java
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentMcpToolsIT.java
@@ -72,14 +72,15 @@ public class LangChain4jAgentMcpToolsIT extends 
CamelTestSupport {
         super.setupResources();
         chatModel = OLLAMA != null ? ModelHelper.loadChatModel(OLLAMA) : 
ModelHelper.loadFromEnv();
 
-        // Initialize tempDirPat
-        tempDirPath = tempDir.toString();
+        // Initialize tempDirPath - use toRealPath() to resolve symlinks 
(e.g., /var -> /private/var on macOS)
+        // This is needed because the MCP filesystem server resolves symlinks 
internally
+        tempDirPath = tempDir.toRealPath().toString();
 
         // Create test file directly
         try {
             Path testFile = tempDir.resolve("camel-mcp-test.txt");
             Files.write(testFile, TEST_FILE_CONTENT.getBytes());
-            testFilePath = testFile.toString();
+            testFilePath = testFile.toRealPath().toString();
         } catch (IOException e) {
             throw new RuntimeException("Failed to create test file", e);
         }
@@ -123,7 +124,8 @@ public class LangChain4jAgentMcpToolsIT extends 
CamelTestSupport {
         mockEndpoint.expectedMessageCount(1);
 
         String response = template.requestBody("direct:chat",
-                "Use your available tools to tell me what is the content of 
camel-mcp-test.txt file?", String.class);
+                "Use your available tools to tell me what is the content of 
the file at " + testFilePath + " ?",
+                String.class);
 
         mockEndpoint.assertIsSatisfied();
         assertNotNull(response, "AI response should not be null");
@@ -154,7 +156,8 @@ public class LangChain4jAgentMcpToolsIT extends 
CamelTestSupport {
         BiPredicate<McpClient, ToolSpecification> securityFilter = (client, 
toolSpec) -> {
             String toolName = toolSpec.name().toLowerCase();
             // Only allow read operations for safety
-            return toolName.contains("read") || toolName.contains("list") || 
toolName.contains("get");
+            return toolName.contains("search") || toolName.contains("read") || 
toolName.contains("list")
+                    || toolName.contains("get");
         };
 
         // Create agent configuration with MCP clients and filter
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentMultimodalityIT.java
 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentMultimodalityIT.java
index a2ac1014d928..1deb09da84af 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentMultimodalityIT.java
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentMultimodalityIT.java
@@ -33,11 +33,13 @@ import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.test.infra.ollama.services.OllamaService;
 import org.apache.camel.test.infra.ollama.services.OllamaServiceFactory;
 import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
 
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeFalse;
 
 /**
  * Integration tests for multimodal content support in the LangChain4j Agent 
component. Tests the ability to send both
@@ -61,6 +63,16 @@ public class LangChain4jAgentMultimodalityIT extends 
CamelTestSupport {
         chatModel = OLLAMA != null ? ModelHelper.loadChatModel(OLLAMA) : 
ModelHelper.loadFromEnv();
     }
 
+    @BeforeEach
+    void skipIfOllama() {
+        boolean isOllama = OLLAMA != null || 
"ollama".equals(System.getenv(ModelHelper.MODEL_PROVIDER));
+        assumeFalse(isOllama,
+                "Skipping multimodality tests with Ollama: LangChain4j's 
Ollama provider does not support " +
+                              "multiple content blocks in a single 
UserMessage. The provider's InternalOllamaHelper.toText() " +
+                              "calls UserMessage.singleText() which requires 
exactly one TextContent. " +
+                              "Use OpenAI or Gemini providers for multimodal 
content testing.");
+    }
+
     /**
      * Tests sending a message with TextContent. This validates that the 
Content parameter works correctly with simple
      * text content.
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentWrappedFileIT.java
 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentWrappedFileIT.java
index b2bff35d4157..bbe6c190a9d3 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentWrappedFileIT.java
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/integration/LangChain4jAgentWrappedFileIT.java
@@ -32,6 +32,8 @@ import 
org.junit.jupiter.api.condition.DisabledIfSystemProperty;
 
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeFalse;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
 
 /**
  * Integration tests for WrappedFile support in the LangChain4j Agent 
component. Tests the ability to process files from
@@ -58,11 +60,17 @@ public class LangChain4jAgentWrappedFileIT extends 
CamelTestSupport {
     protected void setupResources() throws Exception {
         super.setupResources();
 
-        if (!ModelHelper.hasEnvironmentConfiguration()) {
-            throw new IllegalStateException(
-                    "This test requires environment variables: API_KEY, 
MODEL_PROVIDER. "
-                                            + "Optionally: MODEL_BASE_URL, 
MODEL_NAME");
-        }
+        // Skip if no environment configuration - this test requires external 
API providers
+        assumeTrue(ModelHelper.hasEnvironmentConfiguration(),
+                "Skipping: This test requires environment variables: API_KEY, 
MODEL_PROVIDER. " +
+                                                              "Optionally: 
MODEL_BASE_URL, MODEL_NAME");
+
+        // Skip if using Ollama - it doesn't support multimodal content
+        assumeFalse("ollama".equals(System.getenv(ModelHelper.MODEL_PROVIDER)),
+                "Skipping wrapped file tests with Ollama: LangChain4j's Ollama 
provider does not support " +
+                                                                               
 "multimodal content (images, PDFs). The provider's InternalOllamaHelper 
requires "
+                                                                               
 +
+                                                                               
 "single text content in UserMessage. Use OpenAI or Gemini providers for file 
processing tests.");
 
         chatModel = ModelHelper.loadFromEnv();
 
diff --git 
a/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/pojos/TestJsonOutputGuardrail.java
 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/pojos/TestJsonOutputGuardrail.java
index 48c1a825c1ea..1d63412e097d 100644
--- 
a/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/pojos/TestJsonOutputGuardrail.java
+++ 
b/components/camel-ai/camel-langchain4j-agent/src/test/java/org/apache/camel/component/langchain4j/agent/pojos/TestJsonOutputGuardrail.java
@@ -27,6 +27,7 @@ import dev.langchain4j.guardrail.OutputGuardrailResult;
 public class TestJsonOutputGuardrail extends 
JsonExtractorOutputGuardrail<Object> {
 
     private static volatile boolean wasValidated = false;
+    private static volatile boolean allowReprompt = true;
 
     public TestJsonOutputGuardrail() {
         super(Object.class);
@@ -78,8 +79,28 @@ public class TestJsonOutputGuardrail extends 
JsonExtractorOutputGuardrail<Object
         return null;
     }
 
+    @Override
+    protected OutputGuardrailResult invokeInvalidJson(AiMessage aiMessage, 
String json) {
+        if (allowReprompt) {
+            // Default behavior: reprompt to get valid JSON
+            return super.invokeInvalidJson(aiMessage, json);
+        }
+        // Fail immediately without reprompting
+        return fatal("Output validation failed: Invalid JSON format");
+    }
+
+    /**
+     * Sets whether reprompting is allowed when JSON validation fails.
+     *
+     * @param allow true to allow reprompting (default), false to fail 
immediately
+     */
+    public static void setAllowReprompt(boolean allow) {
+        allowReprompt = allow;
+    }
+
     public static void reset() {
         wasValidated = false;
+        allowReprompt = true;
     }
 
     /**

Reply via email to