CAMEL-24334: Add argSchema raw JSON Schema support to camel-ai-tool - #25368
Conversation
Introduce optional argSchema endpoint option for declaring complex nested tool parameters as raw JSON Schema (inline or via classpath/file/resource references). argSchema is mutually exclusive with flat parameter.* options. Derive declared/required argument names from schema properties for executor allowlisting, and adapt LangChain4j tool conversion for nested schemas. Co-authored-by: Cursor Agent <cursoragent@cursor.com>
- Validate required property names against properties map at startup - Handle JSON null and malformed properties/required with clear errors - Strip common JSON Schema metadata before LangChain4j conversion - Regenerate camel-catalog and add edge-case AssertJ tests - Document top-level allowlist behavior for argSchema tools Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Check required tool arguments against the allowlisted argsCopy rather than the original arguments map, so undeclared required names cannot slip through after filtering. Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Implementation summaryThis PR adds optional Highlights
Review feedback addressed
TestingAll targeted tests pass. AI-generated summary on behalf of atiaomar1978-hub via Cursor Cloud Agent. |
Code review fixes (Bugbot + Grok)AI-generated summary on behalf of atiaomar1978-hub via Cursor Cloud Agent. This PR went through automated review (Bugbot + Grok). Below is what was addressed before marking ready for review. Blockers fixed
Security / correctness fixes
LangChain4j adapter
Documentation / metadata
Tests added (AssertJ)18 new test methods added across 4 test classes:
Test run results (2026-08-06)Status: BUILD SUCCESS — all targeted tests pass.
Build time: ~41s (including module dependencies). Known limitations (accepted)
Commits addressing review feedback: |
davsclaus
left a comment
There was a problem hiding this comment.
Thank you for this contribution — the argSchema feature is well-designed with good validation and test coverage.
Two items need attention before this can merge:
Blocking
-
CI has not run — no checks are reported on this branch. Please push to trigger the CI workflow so we can verify the build is green.
-
Unrelated generated file change (scope drift) — the diff includes a
camel.jbang.mcpentry incatalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/jbang/camel-jbang-configuration-metadata.jsonthat has no backing source code in the jbang modules. This appears to be a phantom regeneration artifact from a local build. Please revert this file change from the PR.
Non-blocking convention notes
- The new
testRawArgSchemaConversioninAiToolSpecToLangChain4jTestuses JUnit assertions (assertNotNull,assertEquals,assertTrue) — per project conventions, new test code should prefer AssertJ (assertThat(...)). - New test methods in
AiToolEndpointLifecycleTest,AiToolExecutorTest, andAiToolParameterHelperTestuse thepublicmodifier — JUnit 5 test methods should be package-private (no modifier). - Minor:
copy.argSchema = this.argSchemainAiToolConfiguration.copy()is redundant aftersuper.clone()since String is immutable.
This review covers project rules and conventions only — it does not replace specialized AI review tools (CodeRabbit, Sourcery) or static analysis (SonarCloud).
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of davsclaus
|
🌟 Thank you for your contribution to the Apache Camel project! 🌟 🐫 Apache Camel Committers, please review the following items:
|
- Revert unrelated camel.jbang.mcp catalog metadata change - Use AssertJ in testRawArgSchemaConversion - Drop public modifier from new test methods - Remove redundant argSchema assignment in copy() Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Review feedback addressed (@davsclaus)AI-generated on behalf of atiaomar1978-hub via Cursor Cloud Agent. Pushed commit Blocking
Convention fixes
Tests (BUILD SUCCESS)66 tests, 0 failures/errors/skipped. CI should re-run on this push. Ready for re-review. |
Commit generated AiTool DSL builder updates so CI uncommitted-changes check passes. Co-authored-by: Cursor Agent <cursoragent@cursor.com>
CI fix — uncommitted generated filesAI-generated on behalf of atiaomar1978-hub via Cursor Cloud Agent. CI failed the uncommitted changes check (run 31068754671) because the full build regenerated Fixed in
The unrelated CI should pass the generated-files check on the next run. |
|
🧪 CI tested the following changed modules:
🔬 Scalpel shadow comparison — Scalpel: 16 tested, 26 compile-only — current: 13 all testedMaveniverse Scalpel detected 42 affected modules (current approach: 13).
|
davsclaus
left a comment
There was a problem hiding this comment.
Thank you for addressing the previous review feedback — the CI is green and the jbang metadata file has been reverted.
The argSchema feature is well-designed: proper mutual exclusion validation, comprehensive startup schema validation, good test coverage across unit/lifecycle/executor/langchain4j integration, and clear documentation.
Non-blocking observations
-
Internal LangChain4j API —
dev.langchain4j.internal.JsonSchemaElementJsonUtils.fromMap()is from theinternalpackage and may change without notice in future LangChain4j releases. ThestripSchemaMetadata()fallback mitigates conversion failures, but this remains a maintenance risk worth noting. -
Derived fields in
AiToolSpec.equals/hashCode—declaredArgumentNamesandrequiredArgumentNamesare computed fromparameterDefs/parametersJsonSchema. Including them inequals()andhashCode()is redundant since the source fields already participate. -
Broad
catch (Exception)inresolveResourceContent— the catch-all silently swallows errors when a value isn't a resolvable resource, then treats it as inline JSON. If a user provides a scheme-less resource path (e.g.,schemas/order.json) that fails to load, they would see a confusing JSON parse error rather than a "resource not found" error.
None of these are blocking — the feature is ready to merge.
This review covers project rules and conventions only — it does not replace specialized AI review tools (CodeRabbit, Sourcery) or static analysis (SonarCloud).
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of davsclaus
| @@ -48,11 +53,60 @@ public static ToolSpecification toToolSpecification(AiToolSpec spec) { | |||
|
|
|||
| if (spec.getParameterDefs() != null && !spec.getParameterDefs().isEmpty()) { | |||
| builder.parameters(buildSchema(spec.getParameterDefs())); | |||
There was a problem hiding this comment.
Non-blocking: JsonSchemaElementJsonUtils is from dev.langchain4j.internal — an internal API that may change without notice in future LangChain4j releases. The stripSchemaMetadata() fallback helps, but this is a maintenance risk worth tracking.
| names.add(value.toString()); | ||
| } | ||
| } | ||
| return Set.copyOf(names); |
There was a problem hiding this comment.
Non-blocking: this broad catch (Exception) silently swallows errors for non-resource values. If a user provides a scheme-less resource path like schemas/order.json that fails to load, the error is swallowed and the value is treated as inline JSON — resulting in a confusing JSON parse error rather than a clear "resource not found" error.
gnodet
left a comment
There was a problem hiding this comment.
Well-designed feature addition with proper mutual exclusivity validation, comprehensive startup schema validation, good test coverage (18 new tests), and documentation. All blocking feedback from the prior review round has been addressed, CI is green, and the implementation cleanly extends the existing abstraction so that both LangChain4j and Spring AI adapters work correctly.
The architecture is clean: AiToolSpec stores the resolved JSON schema in parametersJsonSchema regardless of whether it came from flat parameter.* options or argSchema, and all downstream adapters consume from that field. The Spring AI adapter automatically works with argSchema without any code changes, which validates the design.
All four low-severity observations (redundant derived fields in equals/hashCode, double JSON parse in constructor, broad catch in resolveResourceContent, internal LangChain4j API usage) were already documented in davsclaus's approval review — no new issues found.
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of @gnodet
Description
Adds optional
argSchemaendpoint option tocamel-ai-toolfor declaring complex nested tool parameters as raw JSON Schema instead of flatparameter.*options.Key changes:
argSchema@UriParamonAiToolConfiguration(inline JSON orclasspath:/file:/resource:reference)argSchemaandparameter.*are mutually exclusive (validated at consumer start)AiToolSpec.parametersJsonSchema; executor allowlist/required names derived from top-levelproperties/requiredkeysJsonSchemaElementJsonUtils.fromMap()with metadata stripping fallbackrequiredarray, required names must exist in propertiesFixes CAMEL-24334.
Target
mainbranch)Tracking
Apache Camel coding standards and style
mvn clean install -DskipTestslocally from root folder and I have committed all auto-generated changes.AI-assisted contributions
Co-authored-bytrailers) and the PR description identifies the AI tool used.AI-generated on behalf of atiaomar1978-hub via Cursor Cloud Agent.
Testing
All tests pass.