Federico Mariani created CAMEL-26400:
----------------------------------------
Summary: camel-jbang-mcp - camel_eval_expression cannot set
headers, variables, resultType or predicate mode, so an XPath function such as
string() or boolean() fails and header or variable lookups come back null
Key: CAMEL-26400
URL: https://issues.apache.org/jira/browse/CAMEL-26400
Project: Camel
Issue Type: Improvement
Components: camel-jbang, camel-jbang-mcp
Affects Versions: 4.23.0
Reporter: Federico Mariani
Assignee: Federico Mariani
Found on main (4.24.0-SNAPSHOT, commit ffef175654d1); the line numbers below
are from that commit. The same code is in the 4.23.0 release.
h3. Reproduction
{code}
camel_eval_expression
{"language":"xpath","body":"<x><y/></x>","expression":"boolean(/*[local-name()='x'])"}
-> Invalid xpath: boolean(/*[local-name()='x']). Reason: ... XPathException:
Can not convert #BOOLEAN to a NodeList!
camel_eval_expression
{"language":"xpath","body":"<x><y/></x>","expression":"local-name(/*[local-name()='x']/*[1])"}
-> Invalid xpath: ... Can not convert #STRING to a NodeList!
camel_eval_expression {"language":"groovy","expression":"def total =
headers.totalOrdersRows[0].total_orders as long ..."}
-> Cannot invoke method getAt() on null object
camel_eval_expression {"language":"jq","body":"[...]","expression":"[
(variable(\"requestBodyJson\") | fromjson).products[] | ... ]"}
-> JsonQueryTypeException: null (null) only strings can be parsed
{code}
These are correct expressions: in a route the XPath runs with {{resultType:
java.lang.String}} (or as a predicate), and the header or variable is set by an
earlier step. The tool takes only {{expression}}, {{language}}, {{body}} and
{{name}}, so it has no way to evaluate them the way the route will. The XPath
language evaluates to a node set by default, and the scratch exchange has no
headers or variables.
Eval evidence (200 trials on 4.24.0-SNAPSHOT): 9 failed calls.
* 5 XPath calls ({{string()}}, {{boolean()}}, {{local-name()}},
{{not(boolean(...))}}): GLM 5.3, 3 trials. In one of them the route was failing
with the same "Invalid xpath ... #BOOLEAN to a NodeList" (an XPath boolean
written as an expression), and the agent used the tool to find out why. 3 tries
in a row, then it gave up on the tool and read the xpath doc.
* 4 calls that read a header or variable the tool cannot set: Claude Haiku 5.5
(groovy {{headers.x}}, 1), GLM 5.3 (jq {{variable(...)}}, 3). GLM tried to put
the value in as a default argument, then wrote the JSON into the expression
itself.
h3. Cause
* The MCP wrapper and the shared tool take no headers, variables, resultType or
predicate argument ({{camel-jbang-mcp/.../mcp/AuthoringTools.java:310-321}};
{{camel-jbang-core/.../commands/ai/AuthoringTools.java:388-405}}).
* {{ExpressionEvaluator.evaluateInProcess}} sends only {{language}},
{{predicate}}, {{template}} and {{body}}
({{commands/ai/ExpressionEvaluator.java:122-132}}). The eval action of the CLI
connector already accepts {{headers}} and {{variables}}
({{dsl/camel-cli-connector/.../LocalCliConnector.java:1208-1237}}), and so does
{{EvalLanguageDevConsole}}
({{core/camel-console/.../EvalLanguageDevConsole.java:55-59, 76-94}}).
* Predicate mode is inferred only for simple ({{ExpressionEvaluator.java:72}}),
so an XPath or jsonpath predicate is always evaluated as an expression.
* {{EvalLanguageDevConsole}} and {{ExpressionEvaluator.evaluateWith}}
({{:194-226}}) call {{language.createExpression(text)}} with no language
options, so an XPath expression keeps its default NODESET result type.
h3. Fix
* {{camel_eval_expression}} gets optional {{headers}} and {{variables}} (JSON
objects, or {{key=value}} lines like {{camel_runtime_send}}). They go to the
eval action, which already supports them, and are set on the scratch exchange
for local evaluation.
* An optional {{predicate}} (boolean) for every language, in place of the
simple-only guess (keep the guess as the default for simple).
* An optional {{resultType}} (e.g. {{java.lang.String}},
{{java.lang.Boolean}}), passed as the language's own option (XPath, jsonpath,
jq), in {{EvalLanguageDevConsole}} and in {{evaluateWith}}.
* When XPath fails with "Can not convert #STRING/#BOOLEAN/#NUMBER to a
NodeList", answer with the fix: "this XPath returns a string: pass resultType
java.lang.String (in the route: xpath: {expression: ..., resultType:
java.lang.String}), or predicate=true for a boolean", in the same shape as the
CAMEL-25952 hint.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)