Skip to content

CAMEL-23950: complete AgentConfiguration coverage of AiServices builder - #25274

Draft
gnodet wants to merge 3 commits into
mainfrom
fix/CAMEL-23950-complete-agent-config
Draft

CAMEL-23950: complete AgentConfiguration coverage of AiServices builder#25274
gnodet wants to merge 3 commits into
mainfrom
fix/CAMEL-23950-complete-agent-config

Conversation

@gnodet

@gnodet gnodet commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Claude Code on behalf of gnodet

Summary

Completes AgentConfiguration coverage of the LangChain4j AiServices builder API, following up on CAMEL-23928.

Added

  • Guardrail instances (inputGuardrails / outputGuardrails): pre-instantiated guardrail objects for DI-friendly usage (Spring/Quarkus CDI), complementing the existing class-based support. This is a prerequisite for CAMEL-23344 (route-based guardrails that need a CamelContext-aware instance)
  • Guardrail configuration (inputGuardrailsConfig / outputGuardrailsConfig): config objects controlling retry policies and other guardrail behavior
  • Tool execution hooks (beforeToolExecution / afterToolExecution): callbacks invoked before/after each tool execution — the natural hook for per-tool-call logging, Camel events, Micrometer metrics and OTel spans. Foundation for CAMEL-23861

Deliberately not added

  • maxSequentialToolsInvocations: deprecated alias for maxToolCallingRoundTrips (already exposed) since LangChain4j 1.15.0
  • immediateReturnToolNames: no standalone AiServices builder method; already available via ToolProviderResult in the ToolProvider path (used by Camel route tools and MCP tools)

Also

  • Improved aiServicesCustomizer Javadoc to document the chatRequestTransformer conflict with responseFormat/structured output
  • Documented builder options deliberately left for the escape hatch (toolSearchStrategy, storeRetrievedContentInChatMemory, AiServiceListener)

Test plan

  • Added unit tests for all 6 new fields in AgentConfigurationTest (getter/setter, fluent chaining, default values)
  • Updated testFluentChaining() to include all new fields
  • Module tests pass: 195 tests, 0 failures
  • CI green

🤖 Generated with Claude Code

Add the following configuration options to AgentConfiguration, wired in
AbstractAgent.configureBuilder() with null guards:

- inputGuardrails / outputGuardrails (List<InputGuardrail> / List<OutputGuardrail>):
  pre-instantiated guardrail instances for DI-friendly usage (Spring/Quarkus CDI),
  complementing the existing class-based guardrail support
- inputGuardrailsConfig / outputGuardrailsConfig: guardrail configuration objects
  controlling retry policies and other guardrail behavior
- beforeToolExecution / afterToolExecution (Consumer<BeforeToolExecution> /
  Consumer<ToolExecution>): hooks for per-tool-call logging, metrics, and tracing

Deliberately not added:
- maxSequentialToolsInvocations: deprecated alias for maxToolCallingRoundTrips
  (already exposed) since LangChain4j 1.15.0
- immediateReturnToolNames: no standalone AiServices method; already available
  via ToolProviderResult in the ToolProvider path

Also improved aiServicesCustomizer Javadoc to document the chatRequestTransformer
conflict with responseFormat/structured output, and listed builder options
deliberately left for the escape hatch (toolSearchStrategy,
storeRetrievedContentInChatMemory, AiServiceListener).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

Follow JUnit 5 convention per project guidelines: new test methods
use package-private visibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • components/camel-ai/camel-langchain4j-agent-api

🔬 Scalpel shadow comparison — Scalpel: 10 tested, 29 compile-only — current: 10 all tested

Maveniverse Scalpel detected 39 affected modules (current approach: 10).

⚠️ Modules only in Scalpel (29)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

Skip-tests mode would test 10 modules (1 direct + 9 downstream), skip tests for 29 (generated code, meta-modules)

Modules Scalpel would test (10)
  • camel-jbang-mcp
  • camel-jbang-plugin-mcp
  • camel-jbang-plugin-route-parser
  • camel-jbang-plugin-tui
  • camel-jbang-plugin-validate
  • camel-langchain4j-agent
  • camel-langchain4j-agent-api
  • camel-launcher-container
  • camel-yaml-dsl-validator
  • camel-yaml-dsl-validator-maven-plugin
Modules with tests skipped (29)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

All tested modules (39 modules)
  • Camel :: AI :: LangChain4j :: Agent
  • Camel :: AI :: LangChain4j :: Agent :: API
  • Camel :: All Components Sync point
  • Camel :: Assembly
  • Camel :: Catalog :: CSimple Maven Plugin (deprecated)
  • Camel :: Catalog :: Camel Catalog
  • Camel :: Catalog :: Camel Report Maven Plugin
  • Camel :: Catalog :: Camel Route Parser
  • Camel :: Catalog :: Console
  • Camel :: Catalog :: Dummy Component
  • Camel :: Catalog :: Lucene (deprecated)
  • Camel :: Catalog :: Maven
  • Camel :: Catalog :: Suggest
  • Camel :: Component DSL
  • Camel :: Coverage
  • Camel :: Docs
  • Camel :: Endpoint DSL
  • Camel :: Endpoint DSL :: Support
  • Camel :: Integration Tests
  • Camel :: JBang :: Core
  • Camel :: JBang :: Integration tests
  • Camel :: JBang :: MCP
  • Camel :: JBang :: Main
  • Camel :: JBang :: Plugin :: Edit
  • Camel :: JBang :: Plugin :: Generate
  • Camel :: JBang :: Plugin :: Kubernetes
  • Camel :: JBang :: Plugin :: MCP
  • Camel :: JBang :: Plugin :: Route Parser
  • Camel :: JBang :: Plugin :: TUI
  • Camel :: JBang :: Plugin :: Testing
  • Camel :: JBang :: Plugin :: Validate
  • Camel :: Kamelet Main
  • Camel :: Launcher
  • Camel :: Launcher :: Container
  • Camel :: YAML DSL
  • Camel :: YAML DSL :: Deserializers
  • Camel :: YAML DSL :: Maven Plugins
  • Camel :: YAML DSL :: Validator
  • Camel :: YAML DSL :: Validator Maven Plugin

⚙️ View full build and test results

@gnodet
gnodet marked this pull request as ready for review July 31, 2026 11:38
@gnodet
gnodet requested review from Croway and zbendhiba July 31, 2026 11:39

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Clean, well-structured PR that completes AgentConfiguration coverage of the LangChain4j AiServices builder with guardrail instances, guardrail configs, and tool execution hooks.

Highlights:

  • Good decision to document the chatRequestTransformer conflict in the withAiServicesCustomizer Javadoc — this is a non-obvious footgun
  • The @Experimental warnings on BeforeToolExecution and ToolExecution set correct expectations for API stability
  • The "deliberately not added" rationale in the PR description (maxSequentialToolsInvocations as deprecated alias, immediateReturnToolNames with no standalone builder method) shows good API curation judgment

Minor suggestion (non-blocking):

  • AgentConfigurationTest class is still declared public — per project conventions, the public modifier should be dropped (the modified testFluentChaining method and all new methods already use package-private correctly)

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of Guillaume Nodet

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet

gnodet commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review! Fixed — dropped the public qualifier from the AgentConfigurationTest class declaration in 5f00bc1.

Claude Code on behalf of gnodet

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review after new commit: the review feedback from the previous round (drop public from AgentConfigurationTest class declaration) has been correctly addressed. No other changes were made since the last review. LGTM ✅

Claude Code on behalf of Guillaume Nodet

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary (informational — not a formal approval)

Clean, well-structured PR that correctly extends AgentConfiguration to cover remaining AiServices builder options: guardrail instances, guardrail configs, and tool execution hooks. All new LangChain4j API types verified to exist in v1.18.0.

Key observations

  1. API completeness: The six new LangChain4j API types (InputGuardrail, OutputGuardrail, InputGuardrailsConfig, OutputGuardrailsConfig, BeforeToolExecution, ToolExecution) and their corresponding AiServices builder signatures were confirmed in langchain4j 1.18.0.

  2. Good API curation: The "deliberately not added" rationale in the PR description (maxSequentialToolsInvocations as deprecated alias, immediateReturnToolNames with no standalone builder method) demonstrates sound judgment.

  3. Valuable documentation: The chatRequestTransformer conflict warning with responseFormat in the withAiServicesCustomizer Javadoc catches a non-obvious footgun that would silently break structured output.

  4. Clean ordering: New builder calls in configureBuilder follow logical grouping — guardrail instances after guardrail classes, configs after instances, tool hooks in the tool-calling section, and aiServicesCustomizer always last as the escape hatch.

  5. @Experimental warnings: Appropriately noted on BeforeToolExecution and ToolExecution in the Javadoc, since LangChain4j may change these APIs.

Minor notes (non-blocking)

  • New test methods use JUnit assertions (consistent with existing file) rather than AssertJ. Reasonable choice for intra-file consistency.
  • Setting guardrail configs without any corresponding guardrails would pass silently — a future enhancement could log a warning.

Note: This is an informational review only — an agent cannot approve its operator's own PRs. Human review is required.


This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of @gnodet

@davsclaus davsclaus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code on behalf of davsclaus

Clean, well-structured additive API extension. No blocking issues found.

Minor notes:

  1. The Javadoc for withInputGuardrails() states that guardrail classes and instances are "additive on the AiServices builder." Both inputGuardrailClasses() and inputGuardrails() are called independently in configureBuilder() — worth verifying this is truly additive in LangChain4j (rather than last-write-wins) if not already confirmed.

  2. The @Experimental warning on BeforeToolExecution / ToolExecution is well-documented in the Javadoc — just flagging that if LangChain4j changes these, an upgrade-guide entry would be needed.

Everything else looks good: logical placement in configureBuilder(), helpful cross-references in Javadoc, the chatRequestTransformer conflict warning on aiServicesCustomizer is valuable, and tests cover all 6 new fields.

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

@zbendhiba

Copy link
Copy Markdown
Contributor

I have an architecture design and an issue following those JIRA issues aroudn langchain4j, can we revise them, before allowing anyone to contribute?

@zbendhiba zbendhiba left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a general rule: don't add anything to the langchain4j Agent SPI camel-langchain4j-agent-api without describing how it affects the camel-langchain4j-agent component. When you introduce configuration for concepts that already exist in the component (Tools, Guardrails), you need integration tests in the component and a design document explaining when to use one way or the other.

Every configuration added here scales to integration tests in sub-projects too camel-quarkus, camel-spring-boot`). Looking at the JIRA issues, the users requesting these features have deep LangChain4j knowledge. They could create the AiServices themselves. We should discuss whether we want to move to an AiService component instead, and stop adding all those configurations one by one.

@Croway @jamesnetherton @JiriOndrusek

@gnodet

gnodet commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@zbendhiba Thank you for the thoughtful review — these are valid architectural concerns.

You're right that adding configuration fields one-by-one to the SPI scales into integration tests across sub-projects (camel-quarkus, camel-spring-boot), and that users with deep LangChain4j knowledge could create the AiServices builder themselves via withAiServicesCustomizer.

The broader design question — whether an AiService component approach would be better than continuing to mirror the builder API in AgentConfiguration — is worth discussing before proceeding with this PR. I'll put this on hold pending that discussion.

Happy to adapt or close this PR based on the outcome.

Claude Code on behalf of @gnodet

@gnodet
gnodet marked this pull request as draft August 3, 2026 21:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants