oscerd opened a new pull request, #27264:
URL: https://github.com/apache/camel/pull/27264
## Problem
The `camel-ai-tool` contract — documented in "Authorizing what an AI agent
may do in Apache Camel" — is that
Camel copies the **calling exchange** into each tool call, so context set
before the agent runs (most
importantly the authenticated caller's identity kept as an exchange
property) reaches the tool route and the
model cannot set it.
That held for only one runtime:
- **camel-langchain4j-agent** copies it:
`ExchangeHelper.createCopy(exchange, true)` (CAMEL-23944).
- **camel-openai** created a fresh exchange (`McpToolCallExecutor`).
- **camel-spring-ai-chat** created a fresh exchange (`AiToolSpecToSpringAi`).
So with openai or spring-ai driving the loop, a tool route guarded on
`exchangeProperty.subject` saw `null` and
denied every call (fail-closed, but silently broken), and correlation ids /
tenant / variables were lost too.
The no-Java-bean YAML path (`openai:chat-completion?tags=...` against an
OpenAI-compatible endpoint) is hit
hardest.
## Change
A shared helper **`AiToolExecutor.createToolExchange(callingExchange)`** in
camel-ai-tool builds the tool
exchange as an isolated copy of the calling exchange (`exchange.copy()`
carries properties **and** variables;
headers, body and exceptions are isolated). All three route-tool runtimes
now use it, so they can't drift again:
- **camel-openai**: thread the calling exchange through `execute →
executeOne → executeRouteTool` and copy it.
- **camel-spring-ai-chat**: thread it through `getToolCallbacksForTags →
discoverAiRegistryTools → toToolCallback`
and capture it in the tool callback closure.
- **camel-langchain4j-agent**: replace its inline `createCopy` with the
shared helper.
The copy is **not** a pooled consumer exchange, so the now-incorrect
`releaseExchange()` calls on the openai and
spring-ai paths are removed — matching langchain4j, which never released the
copy.
The contract is documented once in the camel-ai-tool component doc ("The
calling exchange").
## Tests
`AiToolExecutorTest.createToolExchangeCopiesCallerContextAndIsolatesHeadersAndBody`:
the copy carries the
caller's property (authenticated subject) and variables, while
header/body/property changes on the tool exchange
do not leak back. Revert-to-red verified (returning a fresh exchange loses
the caller's property).
`mvn clean install -DskipITs` on camel-ai-tool, camel-openai,
camel-langchain4j-agent and camel-spring-ai-chat is
green. No `@UriParam`/metadata change; the only generated file touched is
the catalog mirror of the component doc.
Related: CAMEL-23944. The MCP server bridge (`McpServerBridge`) has no
calling exchange and is tracked separately
by CAMEL-24831.
🤖 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]