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

acosentino pushed a commit to branch 22793-2
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 3664491920aaf341a43e0d31c927b5758f527bf3
Author: Andrea Cosentino <[email protected]>
AuthorDate: Fri Dec 19 10:53:39 2025 +0100

    Added more Langchain4j Agent Guardrails
    
    Signed-off-by: Andrea Cosentino <[email protected]>
---
 .../api/guardrails/CodeInjectionGuardrail.java     | 348 +++++++++++++++++++++
 .../agent/api/guardrails/Guardrails.java           | 136 ++++++++
 .../agent/api/guardrails/LanguageGuardrail.java    | 294 +++++++++++++++++
 .../agent/api/guardrails/NotEmptyGuardrail.java    | 138 ++++++++
 .../api/guardrails/RegexPatternGuardrail.java      | 258 +++++++++++++++
 .../agent/api/guardrails/WordCountGuardrail.java   | 176 +++++++++++
 6 files changed, 1350 insertions(+)

diff --git 
a/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/CodeInjectionGuardrail.java
 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/CodeInjectionGuardrail.java
new file mode 100644
index 000000000000..1e4148a67c39
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/CodeInjectionGuardrail.java
@@ -0,0 +1,348 @@
+/*
+ * 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.component.langchain4j.agent.api.guardrails;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import dev.langchain4j.data.message.UserMessage;
+import dev.langchain4j.guardrail.InputGuardrail;
+import dev.langchain4j.guardrail.InputGuardrailResult;
+
+/**
+ * Input guardrail that detects potential code injection attempts in user 
messages.
+ *
+ * <p>
+ * This guardrail identifies attempts to inject executable code such as:
+ * </p>
+ * <ul>
+ * <li>Shell commands and scripts</li>
+ * <li>SQL injection patterns</li>
+ * <li>JavaScript/HTML injection</li>
+ * <li>Path traversal attempts</li>
+ * <li>Command chaining patterns</li>
+ * </ul>
+ *
+ * <p>
+ * Example usage:
+ * </p>
+ *
+ * <pre>{@code
+ * AgentConfiguration config = new AgentConfiguration()
+ *         .withChatModel(chatModel)
+ *         .withInputGuardrailClasses(List.of(CodeInjectionGuardrail.class));
+ * }</pre>
+ *
+ * @since 4.17.0
+ */
+public class CodeInjectionGuardrail implements InputGuardrail {
+
+    /**
+     * Types of code injection that can be detected.
+     */
+    public enum InjectionType {
+        /** Shell command injection (bash, sh, cmd) */
+        SHELL_COMMAND,
+
+        /** SQL injection patterns */
+        SQL_INJECTION,
+
+        /** JavaScript injection */
+        JAVASCRIPT,
+
+        /** HTML/XSS injection */
+        HTML_XSS,
+
+        /** Path traversal attacks */
+        PATH_TRAVERSAL,
+
+        /** Command chaining (;, &&, ||, |) */
+        COMMAND_CHAINING,
+
+        /** Template injection */
+        TEMPLATE_INJECTION
+    }
+
+    private static final List<InjectionPattern> DEFAULT_PATTERNS = 
Arrays.asList(
+            // Shell command injection
+            new InjectionPattern(
+                    InjectionType.SHELL_COMMAND,
+                    
Pattern.compile("(?i)\\b(bash|sh|cmd|powershell|exec|eval|system)\\s*\\(")),
+            new InjectionPattern(
+                    InjectionType.SHELL_COMMAND,
+                    Pattern.compile("(?i)`[^`]+`")), // Backtick execution
+            new InjectionPattern(
+                    InjectionType.SHELL_COMMAND,
+                    Pattern.compile("(?i)\\$\\([^)]+\\)")), // $() command 
substitution
+            new InjectionPattern(
+                    InjectionType.SHELL_COMMAND,
+                    
Pattern.compile("(?i)\\b(rm|del|format|mkfs|dd)\\s+(-rf?\\s+)?/")),
+
+            // SQL injection
+            new InjectionPattern(
+                    InjectionType.SQL_INJECTION,
+                    
Pattern.compile("(?i)'\\s*(OR|AND)\\s+['\"]?\\d+['\"]?\\s*=\\s*['\"]?\\d+['\"]?")),
+            new InjectionPattern(
+                    InjectionType.SQL_INJECTION,
+                    
Pattern.compile("(?i)(UNION\\s+(ALL\\s+)?SELECT|INSERT\\s+INTO|DELETE\\s+FROM|DROP\\s+TABLE)")),
+            new InjectionPattern(
+                    InjectionType.SQL_INJECTION,
+                    
Pattern.compile("(?i);\\s*(SELECT|INSERT|UPDATE|DELETE|DROP|TRUNCATE)\\b")),
+            new InjectionPattern(
+                    InjectionType.SQL_INJECTION,
+                    Pattern.compile("(?i)--\\s*$")), // SQL comment at end
+
+            // JavaScript injection
+            new InjectionPattern(
+                    InjectionType.JAVASCRIPT,
+                    Pattern.compile("(?i)<script[^>]*>.*?</script>", 
Pattern.DOTALL)),
+            new InjectionPattern(
+                    InjectionType.JAVASCRIPT,
+                    Pattern.compile("(?i)javascript\\s*:")),
+            new InjectionPattern(
+                    InjectionType.JAVASCRIPT,
+                    
Pattern.compile("(?i)\\bon(click|load|error|mouseover|focus)\\s*=")),
+
+            // HTML/XSS
+            new InjectionPattern(
+                    InjectionType.HTML_XSS,
+                    
Pattern.compile("(?i)<(iframe|embed|object|applet|form|input)[^>]*>")),
+            new InjectionPattern(
+                    InjectionType.HTML_XSS,
+                    
Pattern.compile("(?i)\\bstyle\\s*=\\s*['\"].*?(expression|javascript)[^'\"]*['\"]")),
+
+            // Path traversal
+            new InjectionPattern(
+                    InjectionType.PATH_TRAVERSAL,
+                    Pattern.compile("\\.\\.[\\\\/]")),
+            new InjectionPattern(
+                    InjectionType.PATH_TRAVERSAL,
+                    Pattern.compile("(?i)%2e%2e[%/\\\\]")), // URL encoded
+            new InjectionPattern(
+                    InjectionType.PATH_TRAVERSAL,
+                    
Pattern.compile("(?i)\\b(etc/passwd|etc/shadow|windows/system32)")),
+
+            // Command chaining
+            new InjectionPattern(
+                    InjectionType.COMMAND_CHAINING,
+                    Pattern.compile("[;&|]{2}\\s*\\w+")),
+            new InjectionPattern(
+                    InjectionType.COMMAND_CHAINING,
+                    Pattern.compile(";\\s*(cat|ls|dir|type|rm|del)\\b")),
+
+            // Template injection
+            new InjectionPattern(
+                    InjectionType.TEMPLATE_INJECTION,
+                    Pattern.compile("\\{\\{.*?\\}\\}")),
+            new InjectionPattern(
+                    InjectionType.TEMPLATE_INJECTION,
+                    Pattern.compile("\\$\\{.*?\\}")),
+            new InjectionPattern(
+                    InjectionType.TEMPLATE_INJECTION,
+                    Pattern.compile("<%.*?%>")));
+
+    private final List<InjectionPattern> patterns;
+    private final Set<InjectionType> detectTypes;
+    private final boolean strict;
+
+    /**
+     * Creates a guardrail that detects all code injection types.
+     */
+    public CodeInjectionGuardrail() {
+        this(DEFAULT_PATTERNS, EnumSet.allOf(InjectionType.class), false);
+    }
+
+    /**
+     * Creates a guardrail with specific configuration.
+     *
+     * @param patterns    the injection patterns to use
+     * @param detectTypes the types of injection to detect
+     * @param strict      if true, fail on any match; if false, require context
+     */
+    public CodeInjectionGuardrail(List<InjectionPattern> patterns, 
Set<InjectionType> detectTypes, boolean strict) {
+        this.patterns = new ArrayList<>(patterns);
+        this.detectTypes = EnumSet.copyOf(detectTypes);
+        this.strict = strict;
+    }
+
+    /**
+     * Creates a strict guardrail that fails on any code pattern detection.
+     *
+     * @return a new strict CodeInjectionGuardrail
+     */
+    public static CodeInjectionGuardrail strict() {
+        return new CodeInjectionGuardrail(DEFAULT_PATTERNS, 
EnumSet.allOf(InjectionType.class), true);
+    }
+
+    /**
+     * Creates a guardrail that only detects specific injection types.
+     *
+     * @param  types the injection types to detect
+     * @return       a new CodeInjectionGuardrail
+     */
+    public static CodeInjectionGuardrail forTypes(InjectionType... types) {
+        return builder().detectTypes(types).build();
+    }
+
+    /**
+     * Creates a new builder for configuring the guardrail.
+     *
+     * @return a new builder instance
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    @Override
+    public InputGuardrailResult validate(UserMessage userMessage) {
+        if (userMessage == null || userMessage.singleText() == null) {
+            return success();
+        }
+
+        String text = userMessage.singleText();
+        List<InjectionType> detected = new ArrayList<>();
+
+        for (InjectionPattern pattern : patterns) {
+            if (!detectTypes.contains(pattern.getType())) {
+                continue;
+            }
+
+            if (pattern.getPattern().matcher(text).find()) {
+                detected.add(pattern.getType());
+
+                if (strict) {
+                    return failure(String.format(
+                            "Potential code injection detected: %s. " +
+                                                 "Please remove any code or 
command patterns from your message.",
+                            pattern.getType()));
+                }
+            }
+        }
+
+        // In non-strict mode, require multiple different types to reduce 
false positives
+        if (!strict && detected.size() >= 2) {
+            return failure(String.format(
+                    "Multiple potential code injection patterns detected: %s. 
" +
+                                         "Please rephrase your message without 
code-like syntax.",
+                    detected));
+        }
+
+        return success();
+    }
+
+    /**
+     * @return true if running in strict mode
+     */
+    public boolean isStrict() {
+        return strict;
+    }
+
+    /**
+     * @return the set of injection types being detected
+     */
+    public Set<InjectionType> getDetectTypes() {
+        return EnumSet.copyOf(detectTypes);
+    }
+
+    /**
+     * Represents a pattern used to detect code injection attempts.
+     */
+    public static class InjectionPattern {
+        private final InjectionType type;
+        private final Pattern pattern;
+
+        public InjectionPattern(InjectionType type, Pattern pattern) {
+            this.type = type;
+            this.pattern = pattern;
+        }
+
+        public InjectionType getType() {
+            return type;
+        }
+
+        public Pattern getPattern() {
+            return pattern;
+        }
+    }
+
+    /**
+     * Builder for creating CodeInjectionGuardrail instances.
+     */
+    public static class Builder {
+        private List<InjectionPattern> patterns = new 
ArrayList<>(DEFAULT_PATTERNS);
+        private Set<InjectionType> detectTypes = 
EnumSet.allOf(InjectionType.class);
+        private boolean strict = false;
+
+        /**
+         * Sets the injection types to detect.
+         *
+         * @param  types the types to detect
+         * @return       this builder
+         */
+        public Builder detectTypes(InjectionType... types) {
+            this.detectTypes = EnumSet.noneOf(InjectionType.class);
+            this.detectTypes.addAll(Arrays.asList(types));
+            return this;
+        }
+
+        /**
+         * Sets strict mode.
+         *
+         * @param  strict true to fail on any single match
+         * @return        this builder
+         */
+        public Builder strict(boolean strict) {
+            this.strict = strict;
+            return this;
+        }
+
+        /**
+         * Adds a custom injection pattern.
+         *
+         * @param  type    the injection type
+         * @param  pattern the regex pattern
+         * @return         this builder
+         */
+        public Builder addPattern(InjectionType type, Pattern pattern) {
+            this.patterns.add(new InjectionPattern(type, pattern));
+            return this;
+        }
+
+        /**
+         * Clears all default patterns.
+         *
+         * @return this builder
+         */
+        public Builder clearPatterns() {
+            this.patterns.clear();
+            return this;
+        }
+
+        /**
+         * Builds the guardrail instance.
+         *
+         * @return a new CodeInjectionGuardrail instance
+         */
+        public CodeInjectionGuardrail build() {
+            return new CodeInjectionGuardrail(patterns, detectTypes, strict);
+        }
+    }
+}
diff --git 
a/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/Guardrails.java
 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/Guardrails.java
index 46334ea86b6e..dffb190dfafc 100644
--- 
a/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/Guardrails.java
+++ 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/Guardrails.java
@@ -129,9 +129,23 @@ public final class Guardrails {
                 InputLengthGuardrail.class,
                 PiiDetectorGuardrail.class,
                 PromptInjectionGuardrail.class,
+                CodeInjectionGuardrail.class,
                 KeywordFilterGuardrail.class);
     }
 
+    /**
+     * Returns a comprehensive set of output guardrails for secure AI 
responses.
+     *
+     * @return list of comprehensive output guardrail classes
+     */
+    public static List<Class<?>> comprehensiveOutputGuardrails() {
+        return Arrays.asList(
+                NotEmptyGuardrail.class,
+                OutputLengthGuardrail.class,
+                SensitiveDataOutputGuardrail.class,
+                KeywordOutputFilterGuardrail.class);
+    }
+
     // ==================== Input Guardrail Factories ====================
 
     /**
@@ -199,6 +213,43 @@ public final class Guardrails {
         return KeywordFilterGuardrail.blocking(words);
     }
 
+    /**
+     * Creates a code injection guardrail with default settings.
+     *
+     * @return a new CodeInjectionGuardrail instance
+     */
+    public static CodeInjectionGuardrail codeInjection() {
+        return new CodeInjectionGuardrail();
+    }
+
+    /**
+     * Creates a strict code injection guardrail.
+     *
+     * @return a new strict CodeInjectionGuardrail instance
+     */
+    public static CodeInjectionGuardrail codeInjectionStrict() {
+        return CodeInjectionGuardrail.strict();
+    }
+
+    /**
+     * Creates a language guardrail that only allows specific languages.
+     *
+     * @param  languages the languages to allow
+     * @return           a new LanguageGuardrail instance
+     */
+    public static LanguageGuardrail 
languageFilter(LanguageGuardrail.Language... languages) {
+        return LanguageGuardrail.allowOnly(languages);
+    }
+
+    /**
+     * Creates a regex pattern guardrail builder.
+     *
+     * @return a new RegexPatternGuardrail.Builder instance
+     */
+    public static RegexPatternGuardrail.Builder regexPatternBuilder() {
+        return RegexPatternGuardrail.builder();
+    }
+
     // ==================== Output Guardrail Factories ====================
 
     /**
@@ -287,6 +338,55 @@ public final class Guardrails {
         return KeywordOutputFilterGuardrail.redacting(words);
     }
 
+    /**
+     * Creates a word count guardrail with minimum word count.
+     *
+     * @param  minWords minimum required word count
+     * @return          a new WordCountGuardrail instance
+     */
+    public static WordCountGuardrail wordCountAtLeast(int minWords) {
+        return WordCountGuardrail.atLeast(minWords);
+    }
+
+    /**
+     * Creates a word count guardrail with maximum word count.
+     *
+     * @param  maxWords maximum allowed word count
+     * @return          a new WordCountGuardrail instance
+     */
+    public static WordCountGuardrail wordCountAtMost(int maxWords) {
+        return WordCountGuardrail.atMost(maxWords);
+    }
+
+    /**
+     * Creates a word count guardrail with min and max word count.
+     *
+     * @param  minWords minimum required word count
+     * @param  maxWords maximum allowed word count
+     * @return          a new WordCountGuardrail instance
+     */
+    public static WordCountGuardrail wordCountBetween(int minWords, int 
maxWords) {
+        return WordCountGuardrail.between(minWords, maxWords);
+    }
+
+    /**
+     * Creates a not-empty guardrail with default settings.
+     *
+     * @return a new NotEmptyGuardrail instance
+     */
+    public static NotEmptyGuardrail notEmpty() {
+        return new NotEmptyGuardrail();
+    }
+
+    /**
+     * Creates a not-empty guardrail that also detects refusal patterns.
+     *
+     * @return a new NotEmptyGuardrail instance with refusal detection
+     */
+    public static NotEmptyGuardrail notEmptyWithRefusalDetection() {
+        return NotEmptyGuardrail.withRefusalDetection();
+    }
+
     // ==================== Fluent Configuration Builder ====================
 
     /**
@@ -408,6 +508,42 @@ public final class Guardrails {
             return withOutputGuardrail(JsonFormatGuardrail.class);
         }
 
+        /**
+         * Adds code injection detection input guardrail.
+         *
+         * @return this builder
+         */
+        public ConfigurationBuilder withCodeInjectionDetection() {
+            return withInputGuardrail(CodeInjectionGuardrail.class);
+        }
+
+        /**
+         * Adds language validation input guardrail.
+         *
+         * @return this builder
+         */
+        public ConfigurationBuilder withLanguageValidation() {
+            return withInputGuardrail(LanguageGuardrail.class);
+        }
+
+        /**
+         * Adds not-empty output guardrail.
+         *
+         * @return this builder
+         */
+        public ConfigurationBuilder withNotEmptyValidation() {
+            return withOutputGuardrail(NotEmptyGuardrail.class);
+        }
+
+        /**
+         * Adds word count output guardrail.
+         *
+         * @return this builder
+         */
+        public ConfigurationBuilder withWordCountValidation() {
+            return withOutputGuardrail(WordCountGuardrail.class);
+        }
+
         /**
          * Builds the AgentConfiguration with the configured guardrails.
          *
diff --git 
a/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/LanguageGuardrail.java
 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/LanguageGuardrail.java
new file mode 100644
index 000000000000..bf8eea8c7b34
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/LanguageGuardrail.java
@@ -0,0 +1,294 @@
+/*
+ * 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.component.langchain4j.agent.api.guardrails;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import dev.langchain4j.data.message.UserMessage;
+import dev.langchain4j.guardrail.InputGuardrail;
+import dev.langchain4j.guardrail.InputGuardrailResult;
+
+/**
+ * Input guardrail that validates the language of user messages.
+ *
+ * <p>
+ * This guardrail uses character set analysis to detect the script/language 
family of input text. It can be configured
+ * to allow only specific languages or block specific languages.
+ * </p>
+ *
+ * <p>
+ * Example usage:
+ * </p>
+ *
+ * <pre>{@code
+ * // Allow only English
+ * LanguageGuardrail guardrail = LanguageGuardrail.allowOnly(Language.ENGLISH);
+ *
+ * // Allow English and Spanish
+ * LanguageGuardrail guardrail = LanguageGuardrail.builder()
+ *         .allowedLanguages(Language.ENGLISH, Language.LATIN_SCRIPT)
+ *         .build();
+ * }</pre>
+ *
+ * @since 4.17.0
+ */
+public class LanguageGuardrail implements InputGuardrail {
+
+    /**
+     * Detected language/script categories.
+     */
+    public enum Language {
+        /** English and basic Latin characters */
+        ENGLISH(Pattern.compile("^[\\p{ASCII}\\s\\p{Punct}]+$")),
+
+        /** Latin script languages (English, Spanish, French, German, etc.) */
+        LATIN_SCRIPT(Pattern.compile("[\\p{IsLatin}]")),
+
+        /** Cyrillic script (Russian, Ukrainian, etc.) */
+        CYRILLIC(Pattern.compile("[\\p{IsCyrillic}]")),
+
+        /** Chinese characters */
+        CHINESE(Pattern.compile("[\\p{IsHan}]")),
+
+        /** Japanese (Hiragana, Katakana, Kanji) */
+        
JAPANESE(Pattern.compile("[\\p{IsHiragana}\\p{IsKatakana}\\p{IsHan}]")),
+
+        /** Korean (Hangul) */
+        KOREAN(Pattern.compile("[\\p{IsHangul}]")),
+
+        /** Arabic script */
+        ARABIC(Pattern.compile("[\\p{IsArabic}]")),
+
+        /** Hebrew script */
+        HEBREW(Pattern.compile("[\\p{IsHebrew}]")),
+
+        /** Greek script */
+        GREEK(Pattern.compile("[\\p{IsGreek}]")),
+
+        /** Thai script */
+        THAI(Pattern.compile("[\\p{IsThai}]")),
+
+        /** Devanagari script (Hindi, Sanskrit, etc.) */
+        DEVANAGARI(Pattern.compile("[\\p{IsDevanagari}]"));
+
+        private final Pattern pattern;
+
+        Language(Pattern pattern) {
+            this.pattern = pattern;
+        }
+
+        public Pattern getPattern() {
+            return pattern;
+        }
+
+        /**
+         * Checks if the text contains characters from this language/script.
+         */
+        public boolean isPresent(String text) {
+            return pattern.matcher(text).find();
+        }
+    }
+
+    private final Set<Language> allowedLanguages;
+    private final Set<Language> blockedLanguages;
+    private final boolean allowMixed;
+    private final double minLanguageRatio;
+
+    /**
+     * Creates a guardrail that allows all languages.
+     */
+    public LanguageGuardrail() {
+        this(new HashSet<>(), new HashSet<>(), true, 0.0);
+    }
+
+    /**
+     * Creates a guardrail with specific configuration.
+     *
+     * @param allowedLanguages languages to allow (empty = allow all)
+     * @param blockedLanguages languages to block
+     * @param allowMixed       whether to allow mixed language content
+     * @param minLanguageRatio minimum ratio of allowed language characters 
(0.0-1.0)
+     */
+    public LanguageGuardrail(Set<Language> allowedLanguages, Set<Language> 
blockedLanguages,
+                             boolean allowMixed, double minLanguageRatio) {
+        this.allowedLanguages = new HashSet<>(allowedLanguages);
+        this.blockedLanguages = new HashSet<>(blockedLanguages);
+        this.allowMixed = allowMixed;
+        this.minLanguageRatio = minLanguageRatio;
+    }
+
+    /**
+     * Creates a guardrail that only allows specific languages.
+     *
+     * @param  languages the languages to allow
+     * @return           a new LanguageGuardrail instance
+     */
+    public static LanguageGuardrail allowOnly(Language... languages) {
+        return builder().allowedLanguages(languages).build();
+    }
+
+    /**
+     * Creates a guardrail that blocks specific languages.
+     *
+     * @param  languages the languages to block
+     * @return           a new LanguageGuardrail instance
+     */
+    public static LanguageGuardrail block(Language... languages) {
+        return builder().blockedLanguages(languages).build();
+    }
+
+    /**
+     * Creates a new builder for configuring the guardrail.
+     *
+     * @return a new builder instance
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    @Override
+    public InputGuardrailResult validate(UserMessage userMessage) {
+        if (userMessage == null || userMessage.singleText() == null) {
+            return success();
+        }
+
+        String text = userMessage.singleText();
+
+        // Check for blocked languages
+        for (Language blocked : blockedLanguages) {
+            if (blocked.isPresent(text)) {
+                return failure(String.format(
+                        "Message contains blocked language/script: %s", 
blocked.name()));
+            }
+        }
+
+        // If no allowed languages specified, allow all (that aren't blocked)
+        if (allowedLanguages.isEmpty()) {
+            return success();
+        }
+
+        // Check if any allowed language is present
+        boolean hasAllowedLanguage = false;
+        Set<Language> detectedLanguages = new HashSet<>();
+
+        for (Language lang : Language.values()) {
+            if (lang.isPresent(text)) {
+                detectedLanguages.add(lang);
+                if (allowedLanguages.contains(lang)) {
+                    hasAllowedLanguage = true;
+                }
+            }
+        }
+
+        if (!hasAllowedLanguage) {
+            return failure(String.format(
+                    "Message language not allowed. Allowed languages: %s", 
allowedLanguages));
+        }
+
+        // Check for mixed content if not allowed
+        if (!allowMixed && detectedLanguages.size() > 1) {
+            // Check if all detected languages are in allowed set
+            for (Language detected : detectedLanguages) {
+                if (!allowedLanguages.contains(detected) && detected != 
Language.ENGLISH) {
+                    return failure("Mixed language content is not allowed.");
+                }
+            }
+        }
+
+        return success();
+    }
+
+    /**
+     * @return the set of allowed languages
+     */
+    public Set<Language> getAllowedLanguages() {
+        return new HashSet<>(allowedLanguages);
+    }
+
+    /**
+     * @return the set of blocked languages
+     */
+    public Set<Language> getBlockedLanguages() {
+        return new HashSet<>(blockedLanguages);
+    }
+
+    /**
+     * Builder for creating LanguageGuardrail instances.
+     */
+    public static class Builder {
+        private Set<Language> allowedLanguages = new HashSet<>();
+        private Set<Language> blockedLanguages = new HashSet<>();
+        private boolean allowMixed = true;
+        private double minLanguageRatio = 0.0;
+
+        /**
+         * Sets the allowed languages.
+         *
+         * @param  languages the languages to allow
+         * @return           this builder
+         */
+        public Builder allowedLanguages(Language... languages) {
+            this.allowedLanguages.addAll(Arrays.asList(languages));
+            return this;
+        }
+
+        /**
+         * Sets the blocked languages.
+         *
+         * @param  languages the languages to block
+         * @return           this builder
+         */
+        public Builder blockedLanguages(Language... languages) {
+            this.blockedLanguages.addAll(Arrays.asList(languages));
+            return this;
+        }
+
+        /**
+         * Sets whether mixed language content is allowed.
+         *
+         * @param  allowMixed true to allow mixed content
+         * @return            this builder
+         */
+        public Builder allowMixed(boolean allowMixed) {
+            this.allowMixed = allowMixed;
+            return this;
+        }
+
+        /**
+         * Sets the minimum ratio of allowed language characters.
+         *
+         * @param  ratio minimum ratio (0.0-1.0)
+         * @return       this builder
+         */
+        public Builder minLanguageRatio(double ratio) {
+            this.minLanguageRatio = ratio;
+            return this;
+        }
+
+        /**
+         * Builds the guardrail instance.
+         *
+         * @return a new LanguageGuardrail instance
+         */
+        public LanguageGuardrail build() {
+            return new LanguageGuardrail(allowedLanguages, blockedLanguages, 
allowMixed, minLanguageRatio);
+        }
+    }
+}
diff --git 
a/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/NotEmptyGuardrail.java
 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/NotEmptyGuardrail.java
new file mode 100644
index 000000000000..97cc38fd0dbc
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/NotEmptyGuardrail.java
@@ -0,0 +1,138 @@
+/*
+ * 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.component.langchain4j.agent.api.guardrails;
+
+import dev.langchain4j.data.message.AiMessage;
+import dev.langchain4j.guardrail.OutputGuardrail;
+import dev.langchain4j.guardrail.OutputGuardrailResult;
+
+/**
+ * Output guardrail that ensures AI responses are not empty or contain only 
whitespace.
+ *
+ * <p>
+ * This simple guardrail validates that the LLM actually produced a meaningful 
response. It can also check for common
+ * "refusal" patterns where the LLM declines to answer.
+ * </p>
+ *
+ * <p>
+ * Example usage:
+ * </p>
+ *
+ * <pre>{@code
+ * AgentConfiguration config = new AgentConfiguration()
+ *         .withChatModel(chatModel)
+ *         .withOutputGuardrailClasses(List.of(NotEmptyGuardrail.class));
+ * }</pre>
+ *
+ * @since 4.17.0
+ */
+public class NotEmptyGuardrail implements OutputGuardrail {
+
+    private final boolean detectRefusals;
+    private final int minMeaningfulLength;
+
+    /**
+     * Default refusal phrases to detect.
+     */
+    private static final String[] REFUSAL_PATTERNS = {
+            "I cannot", "I can't", "I'm unable to", "I am unable to",
+            "I don't have", "I do not have", "I'm not able to",
+            "I apologize, but I cannot", "Sorry, but I cannot",
+            "I'm sorry, I cannot", "I'm afraid I cannot"
+    };
+
+    /**
+     * Creates a guardrail with default settings.
+     */
+    public NotEmptyGuardrail() {
+        this(false, 1);
+    }
+
+    /**
+     * Creates a guardrail with custom settings.
+     *
+     * @param detectRefusals      whether to detect refusal patterns
+     * @param minMeaningfulLength minimum length for a meaningful response
+     */
+    public NotEmptyGuardrail(boolean detectRefusals, int minMeaningfulLength) {
+        this.detectRefusals = detectRefusals;
+        this.minMeaningfulLength = Math.max(1, minMeaningfulLength);
+    }
+
+    /**
+     * Creates a guardrail that also detects refusal patterns.
+     *
+     * @return a new NotEmptyGuardrail that detects refusals
+     */
+    public static NotEmptyGuardrail withRefusalDetection() {
+        return new NotEmptyGuardrail(true, 1);
+    }
+
+    /**
+     * Creates a guardrail with a minimum meaningful length.
+     *
+     * @param  minLength minimum character length for meaningful response
+     * @return           a new NotEmptyGuardrail instance
+     */
+    public static NotEmptyGuardrail withMinLength(int minLength) {
+        return new NotEmptyGuardrail(false, minLength);
+    }
+
+    @Override
+    public OutputGuardrailResult validate(AiMessage aiMessage) {
+        if (aiMessage == null || aiMessage.text() == null) {
+            return retry("AI response cannot be null. Please try again.");
+        }
+
+        String text = aiMessage.text().trim();
+
+        if (text.isEmpty()) {
+            return retry("AI response is empty. Please provide a meaningful 
response.");
+        }
+
+        if (text.length() < minMeaningfulLength) {
+            return retry(String.format(
+                    "AI response is too short (%d chars). Please provide a 
more complete response.",
+                    text.length()));
+        }
+
+        if (detectRefusals) {
+            String lowerText = text.toLowerCase();
+            for (String pattern : REFUSAL_PATTERNS) {
+                if (lowerText.startsWith(pattern.toLowerCase())) {
+                    return retry("AI declined to answer. Please rephrase the 
question or try again.");
+                }
+            }
+        }
+
+        return success();
+    }
+
+    /**
+     * @return whether refusal detection is enabled
+     */
+    public boolean isDetectRefusals() {
+        return detectRefusals;
+    }
+
+    /**
+     * @return the minimum meaningful length
+     */
+    public int getMinMeaningfulLength() {
+        return minMeaningfulLength;
+    }
+}
diff --git 
a/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/RegexPatternGuardrail.java
 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/RegexPatternGuardrail.java
new file mode 100644
index 000000000000..6e22a42d2b45
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/RegexPatternGuardrail.java
@@ -0,0 +1,258 @@
+/*
+ * 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.component.langchain4j.agent.api.guardrails;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import dev.langchain4j.data.message.UserMessage;
+import dev.langchain4j.guardrail.InputGuardrail;
+import dev.langchain4j.guardrail.InputGuardrailResult;
+
+/**
+ * A flexible input guardrail that uses custom regex patterns for validation.
+ *
+ * <p>
+ * This guardrail allows you to define custom patterns to either block (deny 
patterns) or require (allow patterns) in
+ * user messages. It's useful when you need custom validation beyond the 
built-in guardrails.
+ * </p>
+ *
+ * <p>
+ * Example usage:
+ * </p>
+ *
+ * <pre>{@code
+ * // Block messages containing URLs
+ * RegexPatternGuardrail guardrail = RegexPatternGuardrail.builder()
+ *         .denyPattern("https?://[^\\s]+", "URLs are not allowed")
+ *         .build();
+ *
+ * // Require messages to contain a ticket number
+ * RegexPatternGuardrail guardrail = RegexPatternGuardrail.builder()
+ *         .requirePattern("TICKET-\\d+", "Please include a ticket number 
(e.g., TICKET-123)")
+ *         .build();
+ * }</pre>
+ *
+ * @since 4.17.0
+ */
+public class RegexPatternGuardrail implements InputGuardrail {
+
+    private final List<PatternRule> denyPatterns;
+    private final List<PatternRule> requirePatterns;
+    private final boolean failOnFirstMatch;
+
+    /**
+     * Creates an empty guardrail with no patterns.
+     */
+    public RegexPatternGuardrail() {
+        this(new ArrayList<>(), new ArrayList<>(), true);
+    }
+
+    /**
+     * Creates a guardrail with the specified patterns.
+     *
+     * @param denyPatterns     patterns that will cause validation to fail if 
matched
+     * @param requirePatterns  patterns that must be present for validation to 
pass
+     * @param failOnFirstMatch if true, stop checking after first failure
+     */
+    public RegexPatternGuardrail(List<PatternRule> denyPatterns, 
List<PatternRule> requirePatterns,
+                                 boolean failOnFirstMatch) {
+        this.denyPatterns = new ArrayList<>(denyPatterns);
+        this.requirePatterns = new ArrayList<>(requirePatterns);
+        this.failOnFirstMatch = failOnFirstMatch;
+    }
+
+    /**
+     * Creates a guardrail that blocks messages matching the pattern.
+     *
+     * @param  pattern      the regex pattern to block
+     * @param  errorMessage the error message to show when blocked
+     * @return              a new RegexPatternGuardrail instance
+     */
+    public static RegexPatternGuardrail blocking(String pattern, String 
errorMessage) {
+        return builder().denyPattern(pattern, errorMessage).build();
+    }
+
+    /**
+     * Creates a guardrail that requires messages to match the pattern.
+     *
+     * @param  pattern      the regex pattern to require
+     * @param  errorMessage the error message when pattern is missing
+     * @return              a new RegexPatternGuardrail instance
+     */
+    public static RegexPatternGuardrail requiring(String pattern, String 
errorMessage) {
+        return builder().requirePattern(pattern, errorMessage).build();
+    }
+
+    /**
+     * Creates a new builder for configuring the guardrail.
+     *
+     * @return a new builder instance
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    @Override
+    public InputGuardrailResult validate(UserMessage userMessage) {
+        if (userMessage == null || userMessage.singleText() == null) {
+            return success();
+        }
+
+        String text = userMessage.singleText();
+        List<String> errors = new ArrayList<>();
+
+        // Check deny patterns (should NOT match)
+        for (PatternRule rule : denyPatterns) {
+            if (rule.getPattern().matcher(text).find()) {
+                if (failOnFirstMatch) {
+                    return failure(rule.getErrorMessage());
+                }
+                errors.add(rule.getErrorMessage());
+            }
+        }
+
+        // Check require patterns (MUST match)
+        for (PatternRule rule : requirePatterns) {
+            if (!rule.getPattern().matcher(text).find()) {
+                if (failOnFirstMatch) {
+                    return failure(rule.getErrorMessage());
+                }
+                errors.add(rule.getErrorMessage());
+            }
+        }
+
+        if (!errors.isEmpty()) {
+            return failure(String.join("; ", errors));
+        }
+
+        return success();
+    }
+
+    /**
+     * @return the list of deny patterns
+     */
+    public List<PatternRule> getDenyPatterns() {
+        return new ArrayList<>(denyPatterns);
+    }
+
+    /**
+     * @return the list of require patterns
+     */
+    public List<PatternRule> getRequirePatterns() {
+        return new ArrayList<>(requirePatterns);
+    }
+
+    /**
+     * Represents a pattern rule with an error message.
+     */
+    public static class PatternRule {
+        private final Pattern pattern;
+        private final String errorMessage;
+
+        public PatternRule(Pattern pattern, String errorMessage) {
+            this.pattern = pattern;
+            this.errorMessage = errorMessage;
+        }
+
+        public Pattern getPattern() {
+            return pattern;
+        }
+
+        public String getErrorMessage() {
+            return errorMessage;
+        }
+    }
+
+    /**
+     * Builder for creating RegexPatternGuardrail instances.
+     */
+    public static class Builder {
+        private List<PatternRule> denyPatterns = new ArrayList<>();
+        private List<PatternRule> requirePatterns = new ArrayList<>();
+        private boolean failOnFirstMatch = true;
+
+        /**
+         * Adds a pattern that will cause validation to fail if matched.
+         *
+         * @param  regex        the regex pattern string
+         * @param  errorMessage the error message when matched
+         * @return              this builder
+         */
+        public Builder denyPattern(String regex, String errorMessage) {
+            denyPatterns.add(new PatternRule(Pattern.compile(regex), 
errorMessage));
+            return this;
+        }
+
+        /**
+         * Adds a pattern that will cause validation to fail if matched.
+         *
+         * @param  pattern      the compiled pattern
+         * @param  errorMessage the error message when matched
+         * @return              this builder
+         */
+        public Builder denyPattern(Pattern pattern, String errorMessage) {
+            denyPatterns.add(new PatternRule(pattern, errorMessage));
+            return this;
+        }
+
+        /**
+         * Adds a pattern that must be present for validation to pass.
+         *
+         * @param  regex        the regex pattern string
+         * @param  errorMessage the error message when not matched
+         * @return              this builder
+         */
+        public Builder requirePattern(String regex, String errorMessage) {
+            requirePatterns.add(new PatternRule(Pattern.compile(regex), 
errorMessage));
+            return this;
+        }
+
+        /**
+         * Adds a pattern that must be present for validation to pass.
+         *
+         * @param  pattern      the compiled pattern
+         * @param  errorMessage the error message when not matched
+         * @return              this builder
+         */
+        public Builder requirePattern(Pattern pattern, String errorMessage) {
+            requirePatterns.add(new PatternRule(pattern, errorMessage));
+            return this;
+        }
+
+        /**
+         * Sets whether to fail on first pattern match or collect all errors.
+         *
+         * @param  failOnFirstMatch true to stop at first failure
+         * @return                  this builder
+         */
+        public Builder failOnFirstMatch(boolean failOnFirstMatch) {
+            this.failOnFirstMatch = failOnFirstMatch;
+            return this;
+        }
+
+        /**
+         * Builds the guardrail instance.
+         *
+         * @return a new RegexPatternGuardrail instance
+         */
+        public RegexPatternGuardrail build() {
+            return new RegexPatternGuardrail(denyPatterns, requirePatterns, 
failOnFirstMatch);
+        }
+    }
+}
diff --git 
a/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/WordCountGuardrail.java
 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/WordCountGuardrail.java
new file mode 100644
index 000000000000..4a968fda29be
--- /dev/null
+++ 
b/components/camel-ai/camel-langchain4j-agent-api/src/main/java/org/apache/camel/component/langchain4j/agent/api/guardrails/WordCountGuardrail.java
@@ -0,0 +1,176 @@
+/*
+ * 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.component.langchain4j.agent.api.guardrails;
+
+import dev.langchain4j.data.message.AiMessage;
+import dev.langchain4j.guardrail.OutputGuardrail;
+import dev.langchain4j.guardrail.OutputGuardrailResult;
+
+/**
+ * Output guardrail that validates the word count of AI responses.
+ *
+ * <p>
+ * This guardrail ensures responses meet word count requirements, useful for:
+ * </p>
+ * <ul>
+ * <li>Ensuring detailed responses (minimum words)</li>
+ * <li>Keeping responses concise (maximum words)</li>
+ * <li>Enforcing specific response formats</li>
+ * </ul>
+ *
+ * <p>
+ * Example usage:
+ * </p>
+ *
+ * <pre>{@code
+ * // Ensure responses are at least 50 words
+ * WordCountGuardrail guardrail = WordCountGuardrail.atLeast(50);
+ *
+ * // Ensure responses are between 100 and 500 words
+ * WordCountGuardrail guardrail = WordCountGuardrail.between(100, 500);
+ * }</pre>
+ *
+ * @since 4.17.0
+ */
+public class WordCountGuardrail implements OutputGuardrail {
+
+    /**
+     * Default maximum word count.
+     */
+    public static final int DEFAULT_MAX_WORDS = 10000;
+
+    /**
+     * Default minimum word count.
+     */
+    public static final int DEFAULT_MIN_WORDS = 1;
+
+    private final int minWords;
+    private final int maxWords;
+
+    /**
+     * Creates a guardrail with default word limits.
+     */
+    public WordCountGuardrail() {
+        this(DEFAULT_MIN_WORDS, DEFAULT_MAX_WORDS);
+    }
+
+    /**
+     * Creates a guardrail with custom word limits.
+     *
+     * @param minWords minimum required word count
+     * @param maxWords maximum allowed word count
+     */
+    public WordCountGuardrail(int minWords, int maxWords) {
+        if (minWords < 0) {
+            throw new IllegalArgumentException("minWords cannot be negative");
+        }
+        if (maxWords <= 0) {
+            throw new IllegalArgumentException("maxWords must be positive");
+        }
+        if (minWords > maxWords) {
+            throw new IllegalArgumentException("minWords cannot exceed 
maxWords");
+        }
+        this.minWords = minWords;
+        this.maxWords = maxWords;
+    }
+
+    /**
+     * Creates a guardrail requiring at least the specified number of words.
+     *
+     * @param  minWords minimum required word count
+     * @return          a new WordCountGuardrail instance
+     */
+    public static WordCountGuardrail atLeast(int minWords) {
+        return new WordCountGuardrail(minWords, DEFAULT_MAX_WORDS);
+    }
+
+    /**
+     * Creates a guardrail allowing at most the specified number of words.
+     *
+     * @param  maxWords maximum allowed word count
+     * @return          a new WordCountGuardrail instance
+     */
+    public static WordCountGuardrail atMost(int maxWords) {
+        return new WordCountGuardrail(DEFAULT_MIN_WORDS, maxWords);
+    }
+
+    /**
+     * Creates a guardrail with both minimum and maximum word limits.
+     *
+     * @param  minWords minimum required word count
+     * @param  maxWords maximum allowed word count
+     * @return          a new WordCountGuardrail instance
+     */
+    public static WordCountGuardrail between(int minWords, int maxWords) {
+        return new WordCountGuardrail(minWords, maxWords);
+    }
+
+    @Override
+    public OutputGuardrailResult validate(AiMessage aiMessage) {
+        if (aiMessage == null || aiMessage.text() == null) {
+            return fatal("AI response cannot be null or empty");
+        }
+
+        String text = aiMessage.text().trim();
+        int wordCount = countWords(text);
+
+        if (wordCount < minWords) {
+            return retry(String.format(
+                    "Response too brief: %d words (minimum: %d). Please 
provide a more detailed response.",
+                    wordCount, minWords));
+        }
+
+        if (wordCount > maxWords) {
+            return retry(String.format(
+                    "Response too verbose: %d words (maximum: %d). Please 
provide a more concise response.",
+                    wordCount, maxWords));
+        }
+
+        return success();
+    }
+
+    /**
+     * Counts the number of words in the text.
+     */
+    private int countWords(String text) {
+        if (text == null || text.isEmpty()) {
+            return 0;
+        }
+        String[] words = text.split("\\s+");
+        int count = 0;
+        for (String word : words) {
+            if (!word.isEmpty()) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    /**
+     * @return the minimum required word count
+     */
+    public int getMinWords() {
+        return minWords;
+    }
+
+    /**
+     * @return the maximum allowed word count
+     */
+    public int getMaxWords() {
+        return maxWords;
+    }
+}

Reply via email to