Skip to content

CAMEL-23928: Add AiServices builder customizer and tool-calling options to AgentConfiguration#24485

Draft
davsclaus wants to merge 2 commits into
mainfrom
feature/CAMEL-23928-agent-aiservices-customizer
Draft

CAMEL-23928: Add AiServices builder customizer and tool-calling options to AgentConfiguration#24485
davsclaus wants to merge 2 commits into
mainfrom
feature/CAMEL-23928-agent-aiservices-customizer

Conversation

@davsclaus

Copy link
Copy Markdown
Contributor

Summary

Claude Code on behalf of davsclaus

  • Expose key LangChain4j AiServices builder tool-calling options directly on AgentConfiguration: maxToolCallingRoundTrips, hallucinatedToolNameStrategy, toolExecutionErrorHandler, toolArgumentsErrorHandler, compensateOnToolErrors
  • Add aiServicesCustomizer (Consumer<AiServices<?>>) escape hatch for configuring any AiServices builder option not directly exposed
  • Wire all new options into AbstractAgent.configureBuilder(), with the customizer invoked last

This addresses a gap where users needing tool-calling error handling (e.g. handling hallucinated tool names) had to implement AgentFactory and reimplement all of AbstractAgent.configureBuilder() from scratch.

Follow-up CAMEL-23929 will expose the simple scalar options as @UriParam on LangChain4jAgentConfiguration.

Test plan

  • Unit tests added for all new fluent setters and chaining (AgentConfigurationTest)
  • All 189 tests pass in camel-langchain4j-agent-api
  • Downstream camel-langchain4j-agent module compiles cleanly

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

…zer and tool-calling options to AgentConfiguration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
@github-actions

github-actions Bot commented Jul 7, 2026

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.

@github-actions

github-actions Bot commented Jul 7, 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

@davsclaus davsclaus 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.

Clean, well-structured PR that follows existing patterns. The aiServicesCustomizer escape hatch and tool-calling options are a good addition to avoid users having to reimplement configureBuilder() from scratch.

One minor style nit inline.

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

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
@zbendhiba

Copy link
Copy Markdown
Contributor

I'm analysing this, please hold on before merge.

@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.

Hey @davsclaus , thanks for the PR!

I'm happy you opened this. These are real concerns from users, and I want to address them. I'll definitely work on some of these for the camel-ai-tool (CAMEL-23382).

That said, I looked at how these options work in the context of our current agent component, and I have a few concerns.

Our ToolExecutor already catches errors In LangChain4jAgentProducer, our Camel ToolExecutor catches all exceptions and returns them as strings to the LLM. LangChain4j never sees the exception. So toolExecutionErrorHandler and toolArgumentsErrorHandler would never fire for Camel route tools.
They could work for customTools (raw @tool objects). But we need integration tests to prove it.

Error handling defaults are flipping in langchain4j 2.0
Worth noting: langchain4j is changing the default behavior of both error handlers in 2.0.

  • ToolExecutionErrorHandler currently returns the exception message to the LLM. In 2.0, it will throw instead. The current default is actually a security concern because it can leak internal data to the model.
  • ToolArgumentsErrorHandler currently throws. In 2.0, it will return a text message to the LLM.
    So the defaults are swapping. If we expose these options now without tests, we'll also need to handle the breaking change when we bump to langchain4j 2.0. One more reason to wait and get this right.

compensateOnToolErrors can't work with route tools
This feature relies on @CompensateFor annotations on Java methods. Our tools are Camel routes, not annotated methods. So this option has no effect in the Camel tool model.

Again, it could work with customTools. But we need an integration test.

aiServicesCustomizer vs agent=#myBean

Camel creates the AiServices and manages the builder. If a user wants full control, they can build their own Agent and inject it via agent=#myBean. That already bypasses configureBuilder() entirely.

The customizer runs last and can silently undo what configureBuilder() sets up. I'd rather point users to the existing agent bean injection path. Probably we need to sync on architecture design approval for this.

What I need before we can merge

Integration tests covering both Camel route tools and annotated @tool objects for each option:

  • maxToolCallingRoundTrips (this one I'm pretty confident works)
  • toolExecutionErrorHandler with Camel route tools. Does it actually fire?
  • toolArgumentsErrorHandler. Same question.
  • hallucinatedToolNameStrategy with our dynamic ToolProvider
  • compensateOnToolErrors without @CompensateFor annotations
  • aiServicesCustomizer not breaking the rest of the configuration

If the tests show these options don't work with Camel route tools, I'd rather wait. CAMEL-23382 (camel-ai-tool) is about to land and will
replace the Camel tool executor. Anything touching that area now will be rewritten in a few days. Better to revisit on top of the new tool model.

maxToolCallingRoundTrips is the one option I'm confident about. We could scope this PR to that and move the rest to a follow-up after camel-ai-tool lands.

@davsclaus davsclaus marked this pull request as draft July 7, 2026 10:42
@davsclaus

Copy link
Copy Markdown
Contributor Author

yeah lets park this

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