davsclaus commented on code in PR #28295:
URL: https://github.com/apache/camel/pull/28295#discussion_r4348906047
##########
components/camel-ai/camel-ai-tool/src/main/java/org/apache/camel/component/ai/tool/AiToolExecutor.java:
##########
@@ -99,6 +116,7 @@ public static AiToolResult execute(AiToolSpec spec,
Map<String, Object> argument
// Defensive copy so callers cannot mutate arguments during route
execution
Map<String, Object> argsCopy = arguments != null ? new
HashMap<>(arguments) : new HashMap<>();
+ Map<String, Object> bodyArguments = new HashMap<>(argsCopy);
Review Comment:
(point 2) This copy is taken before the undeclared-argument filter, so the
body gets arguments the schema forbids (`additionalProperties: false`) and the
docs say are allowlisted away. Please build the body from `argsCopy` after
filtering.
##########
components/camel-ai/camel-ai-tool/src/main/docs/ai-tool-component.adoc:
##########
@@ -289,6 +289,58 @@ Supported options: `title`, `readOnlyHint`,
`destructiveHint`, `idempotentHint`,
The `title` option maps to the MCP tool's top-level `title` field (not
`ToolAnnotations.title`). Boolean hint options use nullable configuration: when
unset, Camel omits them from the published MCP tool even though the component
catalog may list `defaultValue: false` for documentation tooling.
+=== Tool Arguments in the Body
+
+By default, tool arguments are exposed as individual headers and the message
body is left unchanged.
+Set `argumentsAsBody=true` to also populate the body with a JSON string
containing the tool-call arguments.
+This is useful when mapping a complete JSON document, for example with Kaoto
Data Mapper.
+
+[source,yaml]
+----
+- route:
+ from:
+ uri: ai-tool:place_order
+ parameters:
+ description: Place a merchandise order
+ argSchema: classpath:place-order.args.schema.json
+ argumentsAsBody: true
+ steps:
+ - to:
+ uri: direct:mapOrder
+----
+
+For a tool call with a customer name and two items, `direct:mapOrder` receives
this JSON-string body:
+
+[source,json]
+----
+{
+ "customerName": "Alice",
+ "items": [
+ { "sku": "TSHIRT", "quantity": 2 },
+ { "sku": "MUG", "quantity": 1 }
+ ]
+}
+----
+
+Nested objects, arrays and JSON value types are preserved. A call with no
arguments produces `{}`.
+The body includes undeclared arguments supplied by the model; individual
headers still include only declared arguments.
Review Comment:
(point 2) This conflicts with line 199 ("Camel always allowlists top-level
property names when invoking the tool route") and with the JIRA's "accepted
arguments".
##########
components/camel-ai/camel-langchain4j-agent/src/main/java/org/apache/camel/component/langchain4j/agent/LangChain4jAgentProducer.java:
##########
@@ -450,7 +450,8 @@ private void addToolToResult(
// not leak into the calling producer exchange, while the caller's
context (properties/variables) reaches
// the tool route. Shared across the route-tool runtimes so they
cannot drift (CAMEL-24832, CAMEL-23944).
Exchange toolExchange =
AiToolExecutor.createToolExchange(exchange);
- AiToolResult result = AiToolExecutor.execute(spec, arguments,
toolExchange);
+ AiToolResult result = AiToolExecutor.execute(spec, arguments,
toolExchange,
+ toolExecutionRequest.id(), memoryId != null ?
memoryId.toString() : null);
Review Comment:
(point 1) `memoryId` is `"default"` here, not null, when the agent has no
memory: LangChain4j falls back to `ChatMemoryService.DEFAULT` when there is no
`@MemoryId` parameter. Pass `null` unless the agent was built with memory.
Comparing with `"default"` is not enough, because a user can pick that id on
purpose.
##########
components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/McpToolCallExecutor.java:
##########
@@ -288,7 +288,7 @@ private ToolResult executeRouteTool(
// exchange property) reaches the tool route; this is not a pooled
consumer exchange, so it is not released
// here (CAMEL-24832)
Exchange toolExchange =
AiToolExecutor.createToolExchange(callingExchange);
- AiToolResult result = AiToolExecutor.execute(spec, argsMap,
toolExchange);
+ AiToolResult result = AiToolExecutor.execute(spec, argsMap,
toolExchange, toolCall.asFunction().id(), null);
Review Comment:
(point 4, not blocking) The Responses API path through this executor has a
conversation id (`CamelOpenAIConversationId` or the `conversationId` option).
It could be passed here instead of `null`.
--
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]