gnodet opened a new pull request, #24991: URL: https://github.com/apache/camel/pull/24991
## Summary _Claude Code on behalf of gnodet_ Fixes three defects in `LangChain4jToolsProducer.toolsChat()` reported in [CAMEL-23943](https://issues.apache.org/jira/browse/CAMEL-23943): 1. **Unbounded tool-calling loop** — The `do/while(true)` loop had no iteration cap, so a misbehaving LLM that keeps requesting tools could loop indefinitely, consuming unbounded tokens and time. Added a configurable `maxToolCallingRoundTrips` endpoint option (default 10) that throws `RuntimeCamelException` when exceeded. 2. **Crash on hallucinated tool names** — `.findFirst().get()` threw `NoSuchElementException` when the LLM hallucinated a tool name not in the registered set. Changed to `.orElse(null)` with a graceful fallback that sends an error message (listing available tools) back to the LLM as a `ToolExecutionResultMessage`, allowing the model to self-correct. 3. **Tool errors swallowed silently** — The catch block set the exception on `toolExchange` but never reported it to the LLM. `ExchangeHelper.copyResults` then propagated it to the main exchange, and the `ToolExecutionResultMessage` was built from an empty/stale body. Now catches both thrown exceptions and processor-set exceptions, sends the error details back to the LLM, and does not pollute the main exchange with the tool failure. ## Changes | File | Change | |------|--------| | `LangChain4jToolsEndpoint.java` | Added `maxToolCallingRoundTrips` `@UriParam` (producer-only, default 10) | | `LangChain4jToolsProducer.java` | Bounded loop guard, safe `.orElse(null)` lookup, error-propagating catch block | | `LangChain4jToolDefectsTest.java` | **New** — 3 test methods exercising each defect with `OpenAIMock` | | Generated files | Auto-regenerated configurer, URI factory, and component JSON | ## Test plan - [x] `testMaxToolCallingRoundTripsExceeded` — mock returns 5 sequential tool calls; producer capped at 2 round trips; verifies `RuntimeCamelException` with the cap value in the message - [x] `testHallucinatedToolNameHandledGracefully` — mock requests `HallucinatedToolXyz`; verifies no crash, no exception on exchange, and a non-null text response from the LLM - [x] `testToolExecutionErrorPropagatedToLLM` — mock requests `FailingTool` whose route throws `RuntimeException`; verifies no exception on exchange and a non-null text response - [x] All 42 existing tests pass (0 failures, 0 errors) 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
