[
https://issues.apache.org/jira/browse/CAMEL-25535?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Federico Mariani updated CAMEL-25535:
-------------------------------------
Description:
{{camel_catalog_example_file}} resolves an example by its short name
(findExample falls back to the name without the group prefix), but then reads
the bundled file from a resource path built from the name the caller passed,
not from the catalog entry's name. Every short name therefore ends in "Could
not read bundled file", although the file is in the jar. The tool's own
argument description uses short names as examples ({{timer-log, rest-api,
circuit-breaker}}), so that is what agents pass.
In an evaluation of coding agents (Claude Code and IBM Bob) on migration tasks,
with camel-jbang-mcp 4.22.1, 25 of the 36 sessions that called
{{camel_catalog_example_file}} hit this; all of them took {{timer-log}}
straight from the argument description, and none ever got the file.
h3. Reproduction
{noformat}
camel_catalog_example_file example: timer-log file: route.camel.yaml
-> File 'route.camel.yaml' not found in example 'timer-log'. Available files:
[README.md, application.properties, timer-log.camel.yaml]
camel_catalog_example_file example: timer-log file: timer-log.camel.yaml
-> Could not read bundled file: examples/timer-log/timer-log.camel.yaml
camel_catalog_example_file example: beginner/timer-log file:
timer-log.camel.yaml
-> works
{noformat}
The resource is {{examples/beginner/timer-log/timer-log.camel.yaml}} (4.22.1)
and {{examples/quick-start/timer-log/timer-log.camel.yaml}} (main).
h3. Cause
{{dsl/camel-jbang/camel-jbang-mcp/.../mcp/ExampleTools.java}},
{{camel_catalog_example_file}} (line 111 at camel-4.22.1, lines 111/125 on
main):
{code:java}
JsonObject entry = ExampleHelper.findExample(catalog, example); //
"timer-log" -> "beginner/timer-log"
...
String resourcePath = "examples/" + example + "/" + file; // uses
"timer-log", not the entry name
{code}
The same code is duplicated in
{{camel-jbang-core/.../commands/ai/ToolRegistry.java}} (the example-file tool
of the shared AI tool registry, line 998 at camel-4.22.1, lines 1148/1157 on
main), so {{camel tui}} and {{camel ask}} have the same bug. The two copies
already diverge (the core one returns the error as a string, the MCP one
throws).
The argument description of {{file}} also gives {{route.camel.yaml}} as an
example, which exists in only one example at 4.22.1 (eip/circuit-breaker) and
in none on main; most agents tried it first and got the "not found" answer.
h3. Fix
* Make {{ExampleTools}} ({{camel_catalog_examples}},
{{camel_catalog_example_file}}) thin wrappers of the registry tools, as
{{AuthoringTools}} already is for the other shared tools, and fix the resource
path once: build it from {{entry.getString("name")}} and return that full name
in the result's {{example}} field.
* Use full names in the {{example}} argument description (e.g.
{{quick-start/timer-log}}), and a file name that exists for that example in the
{{file}} one.
* A test that reads one file of every bundled example by its short name would
have caught it.
* {{camel_catalog_examples level: beginner}} answered 0 examples in 7 of 7
calls on one task while {{database/sql}} exists at {{intermediate}}; the levels
on main are the ladder {{quick-start ... showcase}}
({{ExampleTools.java:54-56}}) and the doc page (camel-jbang-mcp.adoc, "Example
Catalog") still says {{beginner|intermediate|advanced}}. Align the argument
description, the doc and the answer ("no example at level X; levels are ...").
h3. In the same PR: throwException EIP doc page header
{{camel_catalog_doc throwException-eip}} returns a page whose header is the
Stop EIP's ({{= Stop EIP}}, {{:doctitle: Stop}}, {{:shortname: stop}},
{{:description: Stops the processing of the current message}}), followed by the
throwException content. The header in
{{core/camel-core-engine/src/main/docs/modules/eips/pages/throwException-eip.adoc}}
was copied from stop-eip.adoc; it is the same on main and 4.22.x. An agent
that searched docs for "exception" got this page and read it as the Stop EIP.
The header should read Throw Exception / throwException with its own
description. A one-line doc fix, done with this PR rather than in a ticket of
its own.
_Claude Code on behalf of Croway_
was:
{{camel_catalog_example_file}} resolves an example by its short name
(findExample falls back to the name without the group prefix), but then reads
the bundled file from a resource path built from the name the caller passed,
not from the catalog entry's name. Every short name therefore ends in "Could
not read bundled file", although the file is in the jar. The tool's own
argument description uses short names as examples ({{timer-log, rest-api,
circuit-breaker}}), so that is what agents pass.
In an evaluation of coding agents (Claude Code and IBM Bob) on migration tasks,
with camel-jbang-mcp 4.22.1, 25 of the 36 sessions that called
{{camel_catalog_example_file}} hit this; all of them took {{timer-log}}
straight from the argument description, and none ever got the file.
h3. Reproduction
{noformat}
camel_catalog_example_file example: timer-log file: route.camel.yaml
-> File 'route.camel.yaml' not found in example 'timer-log'. Available files:
[README.md, application.properties, timer-log.camel.yaml]
camel_catalog_example_file example: timer-log file: timer-log.camel.yaml
-> Could not read bundled file: examples/timer-log/timer-log.camel.yaml
camel_catalog_example_file example: beginner/timer-log file:
timer-log.camel.yaml
-> works
{noformat}
The resource is {{examples/beginner/timer-log/timer-log.camel.yaml}} (4.22.1)
and {{examples/quick-start/timer-log/timer-log.camel.yaml}} (main).
h3. Cause
{{dsl/camel-jbang/camel-jbang-mcp/.../mcp/ExampleTools.java}},
{{camel_catalog_example_file}} (line 111 at camel-4.22.1, line 125 on main):
{code:java}
JsonObject entry = ExampleHelper.findExample(catalog, example); //
"timer-log" -> "beginner/timer-log"
...
String resourcePath = "examples/" + example + "/" + file; // uses
"timer-log", not the entry name
{code}
The same code is duplicated in
{{camel-jbang-core/.../commands/ai/ToolRegistry.java}} (the example-file tool
of the shared AI tool registry, line 998 at camel-4.22.1, line 1157 on main),
so {{camel tui}} and {{camel ask}} have the same bug. Nothing in the main
branch changed this.
The argument description of {{file}} also gives {{route.camel.yaml}} as an
example, which exists in only one example at 4.22.1 (eip/circuit-breaker) and
in none on main; most agents tried it first and got the "not found" answer.
h3. Fix
* Build the resource path from {{entry.getString("name")}} in both places, and
return that full name in the result's {{example}} field.
* Use full names in the {{example}} argument description (e.g.
{{quick-start/timer-log}}), and a file name that exists for that example in the
{{file}} one.
* A test that reads one file of every bundled example by its short name would
have caught it.
h3. Related: throwException EIP doc page
{{camel_catalog_doc throwException-eip}} returns a page whose header is the
Stop EIP's ({{= Stop EIP}}, {{:doctitle: Stop}}, {{:shortname: stop}},
{{:description: Stops the processing of the current message}}), followed by the
throwException content. The header in
{{core/camel-core-engine/src/main/docs/modules/eips/pages/throwException-eip.adoc}}
was copied from stop-eip.adoc; it is the same on main and 4.22.x. An agent
that searched docs for "exception" got this page and read it as the Stop EIP.
The header should read Throw Exception / throwException with its own
description.
> camel-jbang-mcp - camel_catalog_example_file cannot read a bundled example
> addressed by its short name (e.g. timer-log)
> -----------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-25535
> URL: https://issues.apache.org/jira/browse/CAMEL-25535
> Project: Camel
> Issue Type: Bug
> Components: camel-jbang-mcp
> Affects Versions: 4.22.1
> Reporter: Federico Mariani
> Priority: Major
>
> {{camel_catalog_example_file}} resolves an example by its short name
> (findExample falls back to the name without the group prefix), but then reads
> the bundled file from a resource path built from the name the caller passed,
> not from the catalog entry's name. Every short name therefore ends in "Could
> not read bundled file", although the file is in the jar. The tool's own
> argument description uses short names as examples ({{timer-log, rest-api,
> circuit-breaker}}), so that is what agents pass.
> In an evaluation of coding agents (Claude Code and IBM Bob) on migration
> tasks, with camel-jbang-mcp 4.22.1, 25 of the 36 sessions that called
> {{camel_catalog_example_file}} hit this; all of them took {{timer-log}}
> straight from the argument description, and none ever got the file.
> h3. Reproduction
> {noformat}
> camel_catalog_example_file example: timer-log file: route.camel.yaml
> -> File 'route.camel.yaml' not found in example 'timer-log'. Available files:
> [README.md, application.properties, timer-log.camel.yaml]
> camel_catalog_example_file example: timer-log file: timer-log.camel.yaml
> -> Could not read bundled file: examples/timer-log/timer-log.camel.yaml
> camel_catalog_example_file example: beginner/timer-log file:
> timer-log.camel.yaml
> -> works
> {noformat}
> The resource is {{examples/beginner/timer-log/timer-log.camel.yaml}} (4.22.1)
> and {{examples/quick-start/timer-log/timer-log.camel.yaml}} (main).
> h3. Cause
> {{dsl/camel-jbang/camel-jbang-mcp/.../mcp/ExampleTools.java}},
> {{camel_catalog_example_file}} (line 111 at camel-4.22.1, lines 111/125 on
> main):
> {code:java}
> JsonObject entry = ExampleHelper.findExample(catalog, example); //
> "timer-log" -> "beginner/timer-log"
> ...
> String resourcePath = "examples/" + example + "/" + file; // uses
> "timer-log", not the entry name
> {code}
> The same code is duplicated in
> {{camel-jbang-core/.../commands/ai/ToolRegistry.java}} (the example-file tool
> of the shared AI tool registry, line 998 at camel-4.22.1, lines 1148/1157 on
> main), so {{camel tui}} and {{camel ask}} have the same bug. The two copies
> already diverge (the core one returns the error as a string, the MCP one
> throws).
> The argument description of {{file}} also gives {{route.camel.yaml}} as an
> example, which exists in only one example at 4.22.1 (eip/circuit-breaker) and
> in none on main; most agents tried it first and got the "not found" answer.
> h3. Fix
> * Make {{ExampleTools}} ({{camel_catalog_examples}},
> {{camel_catalog_example_file}}) thin wrappers of the registry tools, as
> {{AuthoringTools}} already is for the other shared tools, and fix the
> resource path once: build it from {{entry.getString("name")}} and return that
> full name in the result's {{example}} field.
> * Use full names in the {{example}} argument description (e.g.
> {{quick-start/timer-log}}), and a file name that exists for that example in
> the {{file}} one.
> * A test that reads one file of every bundled example by its short name would
> have caught it.
> * {{camel_catalog_examples level: beginner}} answered 0 examples in 7 of 7
> calls on one task while {{database/sql}} exists at {{intermediate}}; the
> levels on main are the ladder {{quick-start ... showcase}}
> ({{ExampleTools.java:54-56}}) and the doc page (camel-jbang-mcp.adoc,
> "Example Catalog") still says {{beginner|intermediate|advanced}}. Align the
> argument description, the doc and the answer ("no example at level X; levels
> are ...").
> h3. In the same PR: throwException EIP doc page header
> {{camel_catalog_doc throwException-eip}} returns a page whose header is the
> Stop EIP's ({{= Stop EIP}}, {{:doctitle: Stop}}, {{:shortname: stop}},
> {{:description: Stops the processing of the current message}}), followed by
> the throwException content. The header in
> {{core/camel-core-engine/src/main/docs/modules/eips/pages/throwException-eip.adoc}}
> was copied from stop-eip.adoc; it is the same on main and 4.22.x. An agent
> that searched docs for "exception" got this page and read it as the Stop EIP.
> The header should read Throw Exception / throwException with its own
> description. A one-line doc fix, done with this PR rather than in a ticket of
> its own.
> _Claude Code on behalf of Croway_
--
This message was sent by Atlassian Jira
(v8.20.10#820010)