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]

Reply via email to