Skip to content

CAMEL-26384: camel-jbang - AI tools: a resource: in both values of a Simple ternary goes before the function, and the list item column message quotes the lines - #28634

Merged
davsclaus merged 2 commits into
mainfrom
CAMEL-26384
Oct 29, 2026

Conversation

@davsclaus

@davsclaus davsclaus commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

https://issues.apache.org/jira/browse/CAMEL-26384

Two findings from the local-model benchmark (r23):

  • Ternary rewrite: ${exchangeProperty.CamelTimerCounter} == 1 ? resource:file:order.json : resource:file:order-bad-email.json was rewritten with both values quoted inside the function, so the body became the text resource:file:order.json (2 of 8 runs then failed with Unrecognized token 'resource'). When both values start with the same resource: and scheme, the prefix now goes before the function: resource:file:${exchangeProperty.CamelTimerCounter == 1 ? 'order.json' : 'order-bad-email.json'}.
  • List item column message: it gave only line and column numbers, and the model sent the same indentation again up to 18 times. It now quotes both lines as written, cut at 120 characters so a long inline value does not grow the hint. The lenient repair that parses this message accepts the quoted form.

Tests: YamlValidatorPropertyHintTest (70), all camel-yaml-dsl-validator tests, all camel-jbang-core AI tool tests (756; AuthoringToolsLenientTest and SourceValidatorSimpleTest rerun after the review change), green.

🤖 Generated with Claude Code

https://claude.ai/code/session_01STT6whBgK1AqsSsUKrnE8m

…Simple ternary goes before the function, and the list item column message quotes the lines

- A top-level ternary whose two values start with the same resource: and scheme is rewritten with that prefix
  before the function: inside it, 'resource:file:order.json' is only the text the body becomes.
- The list item column message quotes the item's line and the list's first line as written; the lenient repair
  reads the quoted form.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STT6whBgK1AqsSsUKrnE8m
Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
@davsclaus davsclaus added this to the 4.24.0 milestone Oct 28, 2026
@github-actions github-actions Bot added the dsl label Oct 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@gnodet-bot gnodet-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Both fixes are correct and well-tested.

  • Ternary prefix hoisting (SimpleChecks.java): Matcher.lookingAt() + scheme.group() semantics are correct — group() returns group(0), the full match. All edge cases are guarded: non-matching schemes stay inside the function, values that equal the scheme exactly (empty remainder) are rejected by first.length() > scheme.end(), and a non-empty prefix prevents double-hoisting.
  • ITEM_COLUMN regex (LenientRepairs.java): the .*? in (?:\".*?\"\))? handles embedded " through backtracking — the engine extends past inner quotes to find the "\) terminator. The ? suffix preserves backward compatibility with old-format messages.
  • quotedLine() (YamlValidator.java): bounds check is correct; preserving leading whitespace is intentional (the model needs the indentation context).

Pre-fix validation: static trace confirms the new aResourceInBothValuesOfATopLevelTernaryGoesBeforeTheFunction test requires the prefix-hoisting logic absent on main — the test would fail without the fix.

This review was generated by an AI agent, Hermès on behalf of @gnodet.

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • dsl/camel-jbang/camel-jbang-core
  • dsl/camel-yaml-dsl/camel-yaml-dsl-validator

🔁 1 test passed only after a retry on JDK 21 (1 retried attempt)

Recovered flaky tests on JDK 21 (1)
Module Test Failed attempts First failure
dsl/camel-jbang/camel-jbang-plugin-tui MonitorStartupTest.browserOnlyServesUntilTheServerStops 1 Connection refused (connect failed)

ℹ️ These tests did not fail the build. Surefire retried them and they passed.
Retries are enabled project-wide by surefire.rerunFailingTestsCount in parent/pom.xml.


🔬 Scalpel shadow comparison — Scalpel: 7 of 708 tested, 8 compile-only — current: 7 all tested

Maveniverse Scalpel detected 7 affected modules (current approach: 7).

Skip-tests mode would test 7 modules (2 direct + 6 downstream), skip tests for 8 (generated code, meta-modules)

Modules Scalpel would test (7)
  • camel-jbang-mcp ← downstream of org.apache.camel:camel-jbang-core
  • camel-jbang-plugin-mcp ← downstream of org.apache.camel:camel-jbang-core
  • camel-jbang-plugin-tui ← downstream of org.apache.camel:camel-jbang-core
  • camel-jbang-plugin-validate ← downstream of org.apache.camel:camel-jbang-core
  • camel-launcher-container ← downstream of org.apache.camel:camel-launcher
  • camel-yaml-dsl-validator ← dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/YamlValidator.java, dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/YamlValidatorPropertyHintTest.java
  • camel-yaml-dsl-validator-maven-plugin ← downstream of org.apache.camel:camel-yaml-dsl-validator
Modules with tests skipped (8)
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-launcher
  • coverage

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

⚠️ Some tests are disabled on GitHub Actions (@DisabledIfSystemProperty(named = "ci.env.name")) and require manual verification:

  • dsl/camel-jbang/camel-jbang-core: 2 test(s) disabled on GitHub Actions

💡 Manual integration tests recommended:

You modified dsl/camel-jbang/camel-jbang-core. The related integration tests in dsl/camel-jbang/camel-jbang-it are excluded from CI. Consider running them manually:

mvn verify -f dsl/camel-jbang/camel-jbang-it -Djbang-it-test
All tested modules (16 modules, 2m 24s total)

Total reactor time: 2m 24s

Module Duration Status
Camel :: JBang :: MCP 45.2s SUCCESS
Camel :: JBang :: Plugin :: Validate 30.1s SUCCESS
Camel :: YAML DSL :: Validator 24.8s SUCCESS
Camel :: JBang :: Plugin :: Kubernetes 14.5s SUCCESS
Camel :: JBang :: Plugin :: Testing 14.1s SUCCESS
Camel :: Coverage 5.4s SUCCESS
Camel :: YAML DSL :: Validator Maven Plugin 3.3s SUCCESS
Camel :: JBang :: Plugin :: Edit 1.5s SUCCESS
Camel :: JBang :: Plugin :: Generate 1.4s SUCCESS
Camel :: JBang :: Plugin :: MCP 1.2s SUCCESS
Camel :: JBang :: Integration tests 0.9s SUCCESS
Camel :: JBang :: Main 0.9s SUCCESS
Camel :: Launcher :: Container 0.8s SUCCESS
Camel :: JBang :: Core n/a
Camel :: JBang :: Plugin :: TUI n/a
Camel :: Launcher n/a

Top 20 slowest modules:

  • Camel :: JBang :: MCP (45.2s)
  • Camel :: JBang :: Plugin :: Validate (30.1s)
  • Camel :: YAML DSL :: Validator (24.8s)
  • Camel :: JBang :: Plugin :: Kubernetes (14.5s)
  • Camel :: JBang :: Plugin :: Testing (14.1s)
  • Camel :: Coverage (5.4s)
  • Camel :: YAML DSL :: Validator Maven Plugin (3.3s)
  • Camel :: JBang :: Plugin :: Edit (1.5s)
  • Camel :: JBang :: Plugin :: Generate (1.4s)
  • Camel :: JBang :: Plugin :: MCP (1.2s)
  • Camel :: JBang :: Integration tests (0.9s)
  • Camel :: JBang :: Main (0.9s)
  • Camel :: Launcher :: Container (0.8s)

⚙️ View full build and test results

@oscerd oscerd left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TL;DR

Comment. Both changes are right and well guarded. The resource: prefix moves out of the ternary only when it is safe to, and the quoted lines keep the one parser of that message working. No blockers.

Blockers: None

Other findings: 1 optional suggestion.

What I checked:

  • Ternary rewrite (SimpleChecks.ternaryInsideOneFunction): the prefix is hoisted only when nothing precedes the function (prefix.isEmpty()), both values start with the same resource:<scheme>:, and both keep a non-empty remainder. Any other shape keeps the earlier quoting, as the two counter-cases in aResourceInBothValuesOfATopLevelTernaryGoesBeforeTheFunction show (another scheme, a non-resource value). The result has the resource:file:${... ? '...' : '...'} form that the method's Javadoc already gives as the target.
  • Quoted lines in the list-item message: on main, LenientRepairs.ITEM_COLUMN is the only code that parses this message. The new optional (?: \(".*?"\))? groups accept both forms. The lazy .*? keeps working when the quoted YAML line itself contains "), because the engine extends the match until the rest of the pattern matches. AuthoringToolsLenientTest runs the validator and then the repair end to end, so its column tests (entriesQuotesAndColumns, aListItemFarOffIsNotMoved, ...) exercise the new message format.

Suggestion (optional): quotedLine quotes the whole line. In a route with a long inline value on that line, such as a JSON body or a long simple expression, the hint grows with it, and the model reads it on every retry. Capping the quoted text (for example at 120 characters with an ellipsis) would keep the hint short. The indentation, which is what the model needs, is at the start of the line anyway.

This is a rules-and-conventions review. It does not replace static analysis tools.

Reviewed with Claude Code on behalf of oscerd. This review was generated by an AI agent and may contain inaccuracies; please verify all suggestions before applying.

…most 120 characters of a line

A long inline value (a JSON body, a long expression) made the hint grow with
it, and the model reads the hint on every retry. The indentation the hint is
about is at the start of the line, so the quote is cut at 120 characters.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
@davsclaus

Copy link
Copy Markdown
Contributor Author

@oscerd thanks, applied in f5facae: quotedLine now cuts the quoted line at 120 characters with ..., the same way the "is not YAML" hint already cuts its text at 40. The new test aLongListItemLineIsCutInTheHint puts a 200-character value on the misindented item line. LenientRepairs.ITEM_COLUMN still matches the cut form, because the lazy .*? runs to the ") that closes the quote. The module's validator tests and AuthoringToolsLenientTest / SourceValidatorSimpleTest in camel-jbang-core are green.

@gnodet-bot thanks for the review.

Claude Code on behalf of davsclaus

@davsclaus davsclaus self-assigned this Oct 29, 2026
@davsclaus davsclaus added the enhancement New feature or request label Oct 29, 2026
@davsclaus
davsclaus merged commit c10d7d6 into main Oct 29, 2026
6 checks passed
@davsclaus
davsclaus deleted the CAMEL-26384 branch October 29, 2026 06:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dsl enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants