[ 
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)

Reply via email to